package com.ctshk.rpc.order.custom.service.impl;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctshk.common.dto.Result;
import com.ctshk.common.enums.*;
import com.ctshk.common.exception.BusinessException;
import com.ctshk.common.model.TokenUser;
import com.ctshk.common.utils.CharUtil;
import com.ctshk.common.utils.DateUtil;
import com.ctshk.common.utils.EntityUtil;
import com.ctshk.common.utils.SnowflakeIdWorker;
import com.ctshk.rpc.custom.dto.insurance.TripScheduleInsuranceDTO;
import com.ctshk.rpc.custom.dto.trip.TripScheduleAdvancedDTO;
import com.ctshk.rpc.custom.dto.trip.TripScheduleDTO;
import com.ctshk.rpc.custom.req.trip.CustomizedTripScheduleDTO;
import com.ctshk.rpc.custom.service.ICustomizedTripScheduleService;
import com.ctshk.rpc.finance.req.bill.BillAddCollectionReq;
import com.ctshk.rpc.finance.req.bill.BillOperateRefundReq;
import com.ctshk.rpc.finance.req.onaccount.UseQuotaReq;
import com.ctshk.rpc.finance.service.IFinanceBillService;
import com.ctshk.rpc.finance.service.IFinanceOnAccountCurrencyQuotaService;
import com.ctshk.rpc.insurance.dto.AcceptDTO;
import com.ctshk.rpc.insurance.dto.InsuranceDTO;
import com.ctshk.rpc.insurance.dto.InsuranceInsuredDTO;
import com.ctshk.rpc.insurance.dto.OfferDTO;
import com.ctshk.rpc.insurance.req.InsuranceUnderwritingReq;
import com.ctshk.rpc.insurance.req.tp.*;
import com.ctshk.rpc.insurance.service.IInsuranceService;
import com.ctshk.rpc.iotc.dto.OperateBankPreferenceQueryDTO;
import com.ctshk.rpc.iotc.dto.OperatePromotionQueryDTO;
import com.ctshk.rpc.iotc.req.*;
import com.ctshk.rpc.iotc.service.IOperateBankPreferenceService;
import com.ctshk.rpc.iotc.service.IOperatePromotionService;
import com.ctshk.rpc.order.custom.code.*;
import com.ctshk.rpc.order.custom.code.CollectionTypeIdCode;
import com.ctshk.rpc.order.custom.constant.Constants;
import com.ctshk.rpc.order.custom.dto.order.*;
import com.ctshk.rpc.order.custom.dto.tourist.TouristReceiptInfoDTO;
import com.ctshk.rpc.order.custom.entity.*;
import com.ctshk.rpc.order.custom.mapper.*;
import com.ctshk.rpc.order.custom.req.order.*;
import com.ctshk.rpc.order.custom.req.schedule.ChangeRuleReq;
import com.ctshk.rpc.order.custom.req.schedule.FeeAdjustReq;
import com.ctshk.rpc.order.custom.req.schedule.VisaReq;
import com.ctshk.rpc.order.custom.service.ICustomizedOrderCollectionService;
import com.ctshk.rpc.order.custom.service.ICustomizedOrderReceiptInsuranceService;
import com.ctshk.rpc.order.custom.service.INumberService;
import com.ctshk.rpc.order.custom.util.OrderUtil;
import com.ctshk.rpc.order.custom.util.PacificUtil;
import com.ctshk.rpc.order.custom.vo.RelationInfoJsonBankPreference;
import com.ctshk.rpc.order.custom.vo.SalesReceiptJson;
import com.ctshk.rpc.stamp.dto.LevyDTO;
import com.ctshk.rpc.stamp.req.LevyRequest;
import com.ctshk.rpc.stamp.service.ILevyService;
import com.ctshk.rpc.system.dto.*;
import com.ctshk.rpc.system.enums.ISCode;
import com.ctshk.rpc.system.req.MainDataCurrencyUpdateStatusReq;
import com.ctshk.rpc.system.req.MainDataPaymentRefundTypeIdReq;
import com.ctshk.rpc.system.req.OrderCollectionSumReq;
import com.ctshk.rpc.system.service.*;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import com.ctshk.rpc.finance.json.FileJson;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 游客收款 服务实现类
 * </p>
 *
 * @author 叶冠峰
 * @since 2021-02-22
 */
@DubboService
public class CustomizedOrderCollectionServiceImpl extends ServiceImpl<CustomizedOrderCollectionMapper, CustomizedOrderCollection> implements ICustomizedOrderCollectionService {

    @Autowired
    private CustomizedOrderCollectionMapper orderCollectionMapper;
    @Autowired
    private CustomizedOrderAmountStatisticsMapper orderAmountStatisticsMapper;
    @Autowired
    private CustomizedOrderTouristInfoMapper orderTouristInfoMapper;
    @Autowired
    private CustomizedOrderMapper orderMapper;
    @Autowired
    private CustomizedOrderTouristFeeAdjustMapper orderTouristFeeAdjustMapper;
    @Autowired
    private CustomizedOrderInsuranceMapper orderInsuranceMapper;
    @Autowired
    private CustomizedOrderInsurancePriceTouristMapper orderInsurancePriceTouristMapper;
    @Autowired
    private CustomizedOrderReceiptMapper orderReceiptMapper;
    @Autowired
    private CustomizedOrderReceiptTouristMapper orderReceiptTouristMapper;
    @Autowired
    private CustomizedOrderInsuranceJoinMapper orderInsuranceJoinMapper;
    @Autowired
    private CustomizedOrderTouristVisaMapper orderTouristVisaMapper;
    @Autowired
    private CustomizedOrderReceiptDetailsMapper orderReceiptDetailsMapper;
    @Autowired
    private CustomizedOrderReceiptInsuranceMapper orderReceiptInsuranceMapper;

    /*@Autowired
    private RedisTemplate<String, Object> redisTemplate;*/


    @DubboReference
    private IOperateBankPreferenceService iOperateBankPreferenceService;
    @DubboReference
    private IMainDataCurrencyService iMainDataCurrencyService;
    @DubboReference
    private ISysUserService sysUserService;
    @DubboReference
    private ISysDepartmentService sysDepartmentService;
    @DubboReference
    private ICustomizedOrderReceiptInsuranceService orderReceiptInsuranceService;
    @DubboReference
    private IOperatePromotionService iOperatePromotionService;
    @DubboReference
    private IInsuranceService insuranceService;
    @Autowired
    private INumberService numberService;
    @DubboReference
    private ICustomizedTripScheduleService tripScheduleService;
    @DubboReference
    private IMainDataCollectionTypeService iMainDataCollectionTypeService;
    @DubboReference
    private IMainDataFieldDataService iMainDataFieldDataService;
    //印花税
    @DubboReference
    private ILevyService levyService;
    //收款/退款方式表
    @DubboReference
    private IMainDataPaymentRefundTypeService iMainDataPaymentRefundTypeService;
    @DubboReference
    private IFinanceBillService billService;
    @DubboReference
    private IMainDataCurrencyService mainDataCurrencyService;
    @DubboReference
    private IFinanceOnAccountCurrencyQuotaService financeOnAccountCurrencyQuotaService;




    /**
     * 收款
     *
     * @param req
     * @param currentUser
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result add(CustomOrderCollectionAddReq req,TokenUser currentUser) {
        Long scheduleId = req.getScheduleId();
        //收款方式标识(1：挂账，2：内部挂账，3：其他)
        int collectWay = 3;
        if (Objects.equals(CollectionWayIdCode.ON_ACCOUNT.getCode(),req.getCollectionWayId())){
            //挂账
            collectWay = 1;
        }else if (Objects.equals(CollectionWayIdCode.INTERNAL_ACCOUNT.getCode(),req.getCollectionWayId())){
            //内部挂账
            collectWay = 2;
            if (StringUtils.isBlank(req.getTripNumber())){
                throw new BusinessException(SystemError.SYS_409,"團號");
            }
            //根据团号获取团期ID
            Long id = tripScheduleService.queryIdByTripNumber(req.getTripNumber());
            if (id == null){
                throw new BusinessException(SystemError.CUSTOM_3006);
            }
            scheduleId = id;
        }
        CustomizedOrder order = orderMapper.selectById(req.getOrderId());
        if (order == null || Objects.equals(order.getIsDeleted(),NumberConstant.ONE.getValue())){
            throw new BusinessException(SystemError.CUSTOM_ORDER_4008);
        }
        //判断是否可以收款
        QueryWrapper<CustomizedOrderAmountStatistics> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(CustomizedOrderAmountStatistics::getOrderId, req.getOrderId());
        CustomizedOrderAmountStatistics statistics = orderAmountStatisticsMapper.selectOne(queryWrapper);
        if (statistics == null){
            throw new BusinessException(SystemError.CUSTOM_ORDER_4008);
        }
        //本次收款总金额
        BigDecimal totalReciveAmount = BigDecimal.ZERO;
        for (CustomOrderCollectionAddItemReq item : req.getItems()){
            BigDecimal hkdAmount = iMainDataCurrencyService.getHkdAmount(item.getCurrencyTypeId(), item.getPaidInAmount());
            totalReciveAmount = totalReciveAmount.add(hkdAmount);
        }

        /*if (totalReciveAmount.compareTo(statistics.getRemainingReceivables()) > 0){
            throw new BusinessException(SystemError.CUSTOM_ORDER_4009);
        }*/
        //更新订单统计
        statistics.setTotalPaidIn(statistics.getTotalPaidIn().add(totalReciveAmount));
        statistics.setRemainingReceivables(statistics.getRemainingReceivables().subtract(totalReciveAmount));
        int updateStatistics = orderAmountStatisticsMapper.updateById(statistics);
        if (updateStatistics <= 0){
            throw new BusinessException(SystemError.SYS_437);
        }
        //获取最小定金
        CustomizedTripScheduleDTO tripSchedule = tripScheduleService.queryByScheduleId(order.getScheduleId());
        if (tripSchedule == null){
            throw new BusinessException(SystemError.CUSTOM_3006);
        }
        //是否计算印花税
        boolean isTax = false;
        if(Objects.equals(Constants.AREA_HK, tripSchedule.getDeparturePlaceId()) && !Objects.equals(Constants.AREA_HK, tripSchedule.getDestinationId())) {
            isTax = true;
        }
        //数据抬头
        Long firstTouristId = req.getItems().get(0).getTouristId();
        CustomizedOrderTouristInfo firstTourist = orderTouristInfoMapper.selectById(firstTouristId);
        String receiptHeader = tripSchedule.getChargePersonName();
        if (org.apache.commons.lang3.StringUtils.isNotBlank(firstTourist.getCnFullname())){
            receiptHeader = firstTourist.getCnFullname();
        }else{
            receiptHeader = firstTourist.getEnFullname();
        }

        //收据（立即打印收据用到）
        CustomizedOrderReceipt receipt = null;
        //收据关联旅客（立即打印收据用到）
//        List<CustomizedOrderReceiptTourist> receiptTouristList = new ArrayList<>();
        LocalDateTime now = LocalDateTime.now();
        //是否立即打印收据
        if (req.getIsPrint().intValue() == NumberConstant.ONE.getValue()){
            receipt = new CustomizedOrderReceipt();
            receipt.setId(SnowflakeIdWorker.nextId());
            receipt.setOrderId(req.getOrderId());
            receipt.setScheduleId(order.getScheduleId());
            receipt.setReceiptHeader(receiptHeader);
            receipt.setReceiptNumber(numberService.getReceiptNumber(currentUser.getId()));
            receipt.setReceiptType(1);
            receipt.setCreateTime(now);
            receipt.setGmtCreate(now);
            receipt.setCreateId(currentUser.getId());
            receipt.setReceiptStatus(1);
            receipt.setIsDeleted(0);
        }
        //新增收款列表
        List<CustomizedOrderCollection> collectionList = new ArrayList<>();
        //    List<Long> collectionIdList = new ArrayList<>();
        //总收款金额
        BigDecimal totalPaidInAmount = new BigDecimal(0);
        //印花税金额
        BigDecimal stampDutyAmount = BigDecimal.ZERO;
        //收款记录ID
        List<Long> collectionId = new ArrayList<>();
        //旅客信息
        List<ReceiptTouristInfoDTO> touristInfoDTOList = new ArrayList<>();
        //新增财务认款请求参数
        List<BillAddCollectionReq> addListReq = new ArrayList<>();

        //旅客收据详情列表
        List<TouristReceiptInfoDTO> touristReceiptInfoList = new ArrayList<>();

        //使用挂账记录列表
        List<UseQuotaReq> useQuotaReqList = new ArrayList<>();
        //支付方式
        List<String> payMethodList = new ArrayList<>();
        //付款方
        List<String> payerList = new ArrayList<>();

        for (CustomOrderCollectionAddItemReq item : req.getItems()) {
            payMethodList.add(item.getCollectionWay());
            payerList.add(item.getPayer());
            //游客统计
            QueryWrapper<CustomizedOrderTouristInfo> queryWrapper2 = new QueryWrapper<>();
            queryWrapper2.lambda().eq(CustomizedOrderTouristInfo::getOrderId, req.getOrderId());
            queryWrapper2.lambda().eq(CustomizedOrderTouristInfo::getId, item.getTouristId());
            queryWrapper2.lambda().eq(CustomizedOrderTouristInfo::getIsDeleted, 0);
            CustomizedOrderTouristInfo touristInfo = orderTouristInfoMapper.selectOne(queryWrapper2);

            //旅客收据详情
            TouristReceiptInfoDTO touristReceiptInfoDTO = new TouristReceiptInfoDTO();
            touristReceiptInfoDTO.setTouristId(touristInfo.getId());
            touristReceiptInfoDTO.setReceiptAmount(item.getPaidInAmount());
            touristReceiptInfoList.add(touristReceiptInfoDTO);

            //收据旅客信息
            ReceiptTouristInfoDTO touristInfoDTO = EntityUtil.copy(touristInfo,ReceiptTouristInfoDTO.class);
            touristInfoDTOList.add(touristInfoDTO);
            if (touristInfo.getPayStatus().intValue() == NumberConstant.ONE.getValue()){
                //第一次收款，收款金额不能比“預設訂金+代收費用”的金額低
                BigDecimal minDeposit = null;
                try{
                    minDeposit = tripSchedule.getMinDeposit();
                }catch (Exception e){
                    minDeposit = BigDecimal.ZERO;
                }
                BigDecimal miniAmount = touristInfo.getCollectionFee().add(minDeposit);
                BigDecimal hkdAmount = iMainDataCurrencyService.getHkdAmount(item.getCurrencyTypeId(), item.getPaidInAmount());
                if (miniAmount.compareTo(hkdAmount) > 0){
                    throw new BusinessException(SystemError.CUSTOM_ORDER_4042,touristInfo.getCnFullname(),miniAmount);
                }
            }
            if (req.getBankPreferenceId() != null){
                //使用银行优惠
                if (touristInfo.getTotalPaidIn().compareTo(BigDecimal.ZERO) > 0 && touristInfo.getPayStatus().intValue() != NumberConstant.ONE.getValue()){
                    //实收金额大于0不能使用银行优惠
                    throw new BusinessException(SystemError.CUSTOM_ORDER_4043,touristInfo.getCnFullname());
                }
            }
            //计算印花税
            if (isTax){
                //是否计算过代收费用（代收费用印花税只计算一次）
                if (touristInfo.getIsReceiptCalculated() != null && touristInfo.getIsReceiptCalculated().intValue() == NumberConstant.ONE.getValue()){
                    //是
                    stampDutyAmount = stampDutyAmount.add(item.getPaidInAmount().multiply(new BigDecimal(Constants.STAMP_DUTY_RATIO)));
                }else{
                    //否
                    stampDutyAmount = stampDutyAmount.add((item.getPaidInAmount().subtract(touristInfo.getCollectionFee())).multiply(new BigDecimal(Constants.STAMP_DUTY_RATIO)));
                    touristInfo.setIsReceiptCalculated(1);
                }
            }

            //收款记录
            CustomizedOrderCollection collection = EntityUtil.copy(item, CustomizedOrderCollection.class);
            collection.setId(SnowflakeIdWorker.nextId());
            collection.setPayerId(req.getPayerId());
            BigDecimal hkdAmount = iMainDataCurrencyService.getHkdAmount(item.getCurrencyTypeId(), item.getPaidInAmount());
            collection.setCurrencyPaidInAmount(item.getPaidInAmount());
            collection.setPaidInAmount(hkdAmount);
            collection.setExchangeRate(new BigDecimal(item.getExchangeRate()).doubleValue());
            collection.setGmtCreate(now);
            collection.setIsDeleted(0);
            collection.setCreateId(currentUser.getId());
            collection.setIsPos(req.getIsPos());
            String collectionNumber = StrConstant.SKD.getValue() + DateUtil.fmt(LocalDateTime.now(),"yyMMddHHmmss" + CharUtil.getRandomStr(2));
            collection.setCollectionNumber(collectionNumber);
            collection.setStatus(3);
            collection.setOrderId(req.getOrderId());
            collection.setScheduleId(req.getScheduleId());
            collection.setIsPrint(req.getIsPrint());
            //记录收据Json属性
            collectionId.add(collection.getId());

            //财务认款请求参数
            BillAddCollectionReq addReq = packBillAddCollectionReq(item,collection,tripSchedule,order,currentUser.getId());
            addListReq.add(addReq);

            //内部挂账
            if (collectWay == 1 && Objects.equals(order.getCustomerType(),2)){
                UseQuotaReq useQuotaReq = packOnAccountUsageAddReq(touristInfo,order,collection,order.getBigClientId(),order.getBigClientName(),collectWay,currentUser.getId(),scheduleId);
                useQuotaReqList.add(useQuotaReq);
            }else if (collectWay == 2){
                UserDTO userDTO = sysUserService.queryCacheUser(currentUser.getId());
                UseQuotaReq useQuotaReq = packOnAccountUsageAddReq(touristInfo,order,collection,userDTO.getDeptId(),userDTO.getDept(),collectWay,currentUser.getId(),order.getScheduleId());
                useQuotaReqList.add(useQuotaReq);
            }

            //更新旅客金额统计
            touristInfo.setTotalPaidIn(touristInfo.getTotalPaidIn().add(collection.getPaidInAmount()));
            touristInfo.setRemainingReceivables(touristInfo.getRemainingReceivables().subtract(collection.getPaidInAmount()));
            //是否全部收完
            if(touristInfo.getTotalPaidIn().compareTo(touristInfo.getTotalReceivables()) >= 0){
                touristInfo.setPayStatus(3);
            } else if(touristInfo.getTotalPaidIn().compareTo(new BigDecimal(0)) > 0 &&
                    touristInfo.getTotalPaidIn().compareTo(touristInfo.getTotalReceivables()) < 0){
                touristInfo.setPayStatus(2);
            }
            collection.setTotalReceivables(touristInfo.getTotalReceivables());
            collectionList.add(collection);
            //    collectionIdList.add(collection.getId());
            //更新旅客信息
            int update = orderTouristInfoMapper.updateById(touristInfo);
            if (update <= 0){
                throw new BusinessException(SystemError.SYS_437);
            }
            //总收款金额
            totalPaidInAmount = totalPaidInAmount.add(collection.getPaidInAmount());
        }
        if (receipt != null){
            receipt.setReceiptAmount(totalPaidInAmount);
            receipt.setIncludeTouristNum(collectionList.size());
        }
        //银行优惠(大客户挂账)
        Result<OperateBankPreferenceQueryDTO> preferenceQueryDTOResult = null;
        CustomOrderCollectionAddItemReq firstItem = req.getItems().get(0);
        if (req.getBankPreferenceId() != null) {
            OperateBankConformQueryReq bankPreferenceQueryReq = new OperateBankConformQueryReq();
            bankPreferenceQueryReq.setId(req.getBankPreferenceId());
            bankPreferenceQueryReq.setBusinessType(2);
            bankPreferenceQueryReq.setCardNumber(firstItem.getPayer());
            bankPreferenceQueryReq.setChannelId(12345678902L);
            bankPreferenceQueryReq.setRelationId(req.getScheduleId());
            bankPreferenceQueryReq.setUserId(currentUser.getId());
            bankPreferenceQueryReq.setTotalPaidIn(totalPaidInAmount);
            bankPreferenceQueryReq.setDiscountObjectId(12345678L);
            preferenceQueryDTOResult = iOperateBankPreferenceService.queryConform(bankPreferenceQueryReq);
        }
        //总银行优惠金额
        BigDecimal totalBankPreferenceAmount = new BigDecimal(0);
        //银行优惠
        List<CustomizedOrderCollection> bankPreferenceList = new ArrayList<>();
        if (preferenceQueryDTOResult != null && preferenceQueryDTOResult.isSuccess() && preferenceQueryDTOResult.getData() != null) {
            OperateBankPreferenceQueryDTO preferenceQueryDTO = preferenceQueryDTOResult.getData();
            if (Objects.equals(preferenceQueryDTO.getDiscountType(), NumberConstant.ONE.getValue())) {
                //优惠类型：满减
                if (totalPaidInAmount.compareTo(preferenceQueryDTO.getFullAmount()) >= 0) {
                    BigDecimal bankPreference = totalPaidInAmount.subtract(preferenceQueryDTO.getReductionAmount());
                    totalBankPreferenceAmount = totalBankPreferenceAmount.add(bankPreference);
                }
            } else if (Objects.equals(preferenceQueryDTO.getDiscountType(), NumberConstant.TWO.getValue())) {
                //优惠类型：折扣
                BigDecimal bankPreference = totalPaidInAmount.subtract(totalPaidInAmount.multiply(
                        BigDecimal.valueOf(preferenceQueryDTO.getDiscountPercent())));
                if (bankPreference.compareTo(preferenceQueryDTO.getMaxDiscount()) > 0) {
                    totalBankPreferenceAmount = totalBankPreferenceAmount.add(preferenceQueryDTO.getMaxDiscount());
                } else {
                    totalBankPreferenceAmount = totalBankPreferenceAmount.add(bankPreference);
                }
            }
            //人均优惠金额
            BigDecimal avgDiscountAmount = totalBankPreferenceAmount.divide(new BigDecimal(collectionList.size()), 2, BigDecimal.ROUND_HALF_DOWN);
            //全款
            MainDataFieldDataDTO collectionTypeDTO = iMainDataFieldDataService.queryFieldData(CollectionTypeIdCode.FULL.getCode());
            if(collectionTypeDTO == null) {
                return Result.failed(SystemError.SYS_411);
            }
            //遍历收款
            for (int i = 0;i < collectionList.size();i++){
                CustomizedOrderCollection collection = collectionList.get(i);
                collection.setCollectionTypeId(collectionTypeDTO.getId());
                collection.setCollectionType(collectionTypeDTO.getFieldValue());
                collection.setCollectionWayId(CollectionWayIdCode.BANK_DISCOUNT.getCode());
                collection.setCollectionWay(CollectionWayIdCode.BANK_DISCOUNT.getMsg());
                //新增银行优惠收款记录
                CustomizedOrderCollection bankPreferenceCollection = EntityUtil.copy(collection, CustomizedOrderCollection.class);
                bankPreferenceCollection.setId(SnowflakeIdWorker.nextId());
                bankPreferenceCollection.setCurrencyType(CurrencyIdCode.HKD.getMsg());
                bankPreferenceCollection.setCurrencyTypeId(CurrencyIdCode.HKD.getCode());
                bankPreferenceCollection.setCollectionTypeId(collectionTypeDTO.getId());
                bankPreferenceCollection.setCollectionType(collectionTypeDTO.getFieldValue());
                bankPreferenceCollection.setCollectionWayId(CollectionWayIdCode.BANK_DISCOUNT.getCode());
                bankPreferenceCollection.setCollectionWay(CollectionWayIdCode.BANK_DISCOUNT.getMsg());
                if (i < (collectionList.size() - 1)){
                    //非最后一个正常取值
                    collection.setCurrencyPaidInAmount(avgDiscountAmount);
                    bankPreferenceCollection.setCurrencyPaidInAmount(avgDiscountAmount);
                }else{
                    //最后一个旅客的优惠取余数
                    BigDecimal remainDiscountAmount = totalBankPreferenceAmount.subtract(avgDiscountAmount.multiply(new BigDecimal(collectionList.size() - 1)));
                    collection.setCurrencyPaidInAmount(remainDiscountAmount);
                    bankPreferenceCollection.setCurrencyPaidInAmount(remainDiscountAmount);
                }
                //清空copy的部分不需要内容
                bankPreferenceCollection.setPayer(null);
                bankPreferenceCollection.setRemark(null);
                bankPreferenceCollection.setCollectionVoucherNum(null);
                bankPreferenceCollection.setCollectionVoucherJson(null);
                //金额为0不作处理
                if(bankPreferenceCollection.getCurrencyPaidInAmount().compareTo(new BigDecimal(0)) == 0) {
                    continue;
                }
                //收款记录关联json
                RelationInfoJsonBankPreference relationInfoJson = new RelationInfoJsonBankPreference();
                relationInfoJson.setDiscountId(req.getBankPreferenceId());
                bankPreferenceCollection.setRelationInfoJson(JSON.toJSONString(relationInfoJson));
                bankPreferenceList.add(bankPreferenceCollection);
            }
            //合并数组
            collectionList.addAll(bankPreferenceList);

            //使用优惠
            OperateBankDeductReq deductReq = new OperateBankDeductReq();
            deductReq.setId(req.getBankPreferenceId());
            deductReq.setTotalPaidIn(totalBankPreferenceAmount);
            deductReq.setRelationId(req.getScheduleId());
            deductReq.setProductNumber(tripSchedule.getTripNumber());
            deductReq.setProductName(tripSchedule.getName());
            deductReq.setCardNumber(firstItem.getPayer());
            deductReq.setBusinessType(SystemBusinessType.OUTBOUND_CUSTOMIZATION.getCode());
            //TODO
            /*deductReq.setDiscountObjectId();
            deductReq.setChannelId();*/
            Result deduct = iOperateBankPreferenceService.deduct(deductReq, currentUser);
            if (deduct == null || deduct.getCode() != 0){
                log.error("使用银联优惠报错：code = "+deduct.getCode()+" ,msg = " + deduct.getMsg());
                throw new BusinessException(SystemError.SYS_408);
            }

        }
        //批量新增收款记录
        boolean bl = saveBatch(collectionList);
        if (!bl){
            throw new BusinessException(SystemError.SYS_437);
        }
        //是否立即打印收据
        if (req.getIsPrint().intValue() == NumberConstant.ONE.getValue()){
            //新增收据
            int insertReceipt = orderReceiptMapper.insert(receipt);
            if (insertReceipt <= 0){
                throw new BusinessException(SystemError.SYS_437);
            }
            //收据关联旅客
            /*if (receiptTouristList.size() > 0){
                //批量新增收据关联旅客
                Integer batch = orderReceiptTouristMapper.insertBatchSomeColumn(receiptTouristList);
                if (batch < receiptTouristList.size()){
                    throw new BusinessException(SystemError.SYS_437);
                }
            }*/
            //销售收据
            CustomizedOrderReceiptDetails receiptDetails = new CustomizedOrderReceiptDetails();
            receiptDetails.setId(SnowflakeIdWorker.nextId());
            receiptDetails.setOrderId(order.getId());
            receiptDetails.setScheduleId(order.getScheduleId());
            receiptDetails.setReceiptId(receipt.getId());
            receiptDetails.setReceiptType(1);
            receiptDetails.setTouristName(receiptHeader);
            receiptDetails.setCustomerRights(tripSchedule.getCustomerRights());
            receiptDetails.setReceiptStatus(1);
            receiptDetails.setTeaPartyDate(tripSchedule.getAdvancedDTO().getTeaPartyDate());
            receiptDetails.setTeaPartyTime(tripSchedule.getAdvancedDTO().getTeaPartyTime());
            if (isTax){
                receiptDetails.setStampDutyAmount(stampDutyAmount);
            }

            //销售收据json
            SalesReceiptJson salesReceiptJson = new SalesReceiptJson();
            salesReceiptJson.setPayMethod(payMethodList);
            salesReceiptJson.setPayer(payerList);
            salesReceiptJson.setTouristReceiptInfoList(touristReceiptInfoList);
            salesReceiptJson.setCollectionIdList(collectionId);
            salesReceiptJson.setTouristInfoDTOList(touristInfoDTOList);
            salesReceiptJson.setTourCode(tripSchedule.getTripNumber());
            salesReceiptJson.setDays(tripSchedule.getTravelDays());
            salesReceiptJson.setDepartureDate(tripSchedule.getDepartureDate().toLocalDate());
            salesReceiptJson.setDeliveryDate(tripSchedule.getDepartureDate().toLocalDate().plusDays(tripSchedule.getTravelDays()));
            salesReceiptJson.setDepDate(CharUtil.getWeekDay(tripSchedule.getDepartureDate().getDayOfWeek().getValue()));
            salesReceiptJson.setRoute(tripSchedule.getName());
            salesReceiptJson.setEnquiryNo(CharUtil.getRandomStr(6));
            salesReceiptJson.setEnquiryTimeTel(Constants.QUERY_TIME);
            salesReceiptJson.setReceiptNumber(numberService.getReceiptNumber(currentUser.getId()));
            salesReceiptJson.setCollectionFee(statistics.getCollectionFee());
            salesReceiptJson.setAdjustmentCost(statistics.getAdjustmentCost());
            salesReceiptJson.setOtherAmount(statistics.getOtherAmount());
            salesReceiptJson.setGroupFee(statistics.getTotalTourFee());
            salesReceiptJson.setTotalReceivables(statistics.getTotalReceivables());
            salesReceiptJson.setPaidAmount(statistics.getTotalPaidIn());
            salesReceiptJson.setPayAmount(totalReciveAmount.subtract(totalBankPreferenceAmount));
            salesReceiptJson.setRemainingAmount(statistics.getRemainingReceivables());
            //定制包团须知
            salesReceiptJson.setTourFeeInclude(tripSchedule.getTourFeeInclude());
            salesReceiptJson.setTourFeeExclude(tripSchedule.getTourFeeExclude());
            salesReceiptJson.setSignNotice(tripSchedule.getSignNotice());
            salesReceiptJson.setRemark(tripSchedule.getRemark());
            receiptDetails.setReceipJson(JSON.toJSONString(salesReceiptJson));
            //新增销售收据
            int insertDetial = orderReceiptDetailsMapper.insert(receiptDetails);
            if (insertDetial <= 0){
                throw new BusinessException(SystemError.SYS_437);
            }
            //对接财务认款
            Result result = billService.addCollection(addListReq);
            if (result == null || !result.isSuccess()){
                throw new BusinessException(SystemError.SYS_437);
            }
            //新增财务挂账使用记录
            if (useQuotaReqList.size() > 0 && collectWay != 3){
                Result result1 = financeOnAccountCurrencyQuotaService.useQuota(useQuotaReqList);
                if (result1 == null || !result1.isSuccess()){
                    throw new BusinessException(SystemError.SYS_437);
                }
            }
            //立即打印收据 -> 返回收据ID
            return Result.success(receipt.getId());
        }
        //对接财务认款
        Result result = billService.addCollection(addListReq);
        if (result == null || !result.isSuccess()){
            throw new BusinessException(SystemError.SYS_437);
        }
        //新增财务挂账使用记录
        if (useQuotaReqList.size() > 0 && collectWay != 3){
            Result result1 = financeOnAccountCurrencyQuotaService.useQuota(useQuotaReqList);
            if (result1 == null || !result1.isSuccess()){
                throw new BusinessException(SystemError.SYS_437);
            }
        }
        return Result.success(null);
    }

    /**
     * 封装财务挂账使用记录
     *
     *
     * @param touristInfo
     * @param order
     * @param collection
     * @param bigClientId
     * @param bigClientName
     * @param collectWay
     * @param userId
     * @param scheduleId
     * @return
     */
    private UseQuotaReq packOnAccountUsageAddReq(CustomizedOrderTouristInfo touristInfo, CustomizedOrder order, CustomizedOrderCollection collection, Long bigClientId, String bigClientName, int collectWay, Long userId,Long scheduleId) {
        UseQuotaReq req = new UseQuotaReq();
        req.setUserId(userId);
        req.setAccountType(collectWay);
        if (collectWay == 1){
            req.setAccountId(bigClientId);
        }else if (collectWay == 2){
            req.setDeptId(bigClientId);
        }
        req.setAmount(collection.getCurrencyPaidInAmount());
        req.setBigClientName(bigClientName);
        req.setCollectionTypeId(collection.getCollectionTypeId());
        req.setCollectionTypeName(collection.getCollectionType());
        req.setCollectionWayId(collection.getCollectionWayId());
        req.setCollectionWayName(collection.getCollectionWay());
        req.setBillNumber(collection.getCollectionNumber());
        req.setBusinessType(SystemBusinessType.OUTBOUND_CUSTOMIZATION.getCode());
        req.setCollectionTime(collection.getGmtCreate());
        if (StringUtils.isNotBlank(collection.getCollectionVoucherJson())){
            List<FileJson> fileJsons = JSON.parseArray(collection.getCollectionVoucherJson(), FileJson.class);
            req.setCollectionVoucherJson(fileJsons);
        }
        req.setCurrencyId(collection.getCurrencyTypeId());
        req.setCurrencyName(collection.getCurrencyType());
        req.setExchangeRate(collection.getExchangeRate());
        req.setContactMobile(touristInfo.getMobile());
        req.setTouristName(touristInfo.getCnFullname()==null?touristInfo.getEnFullname():touristInfo.getCnFullname());
        req.setTouristSource(order.getCustomerType());
        req.setSaleOrderId(order.getId());
        req.setSaleOrderNumber(order.getOrderNumber());
        req.setProductId(order.getScheduleId());
        TripScheduleDTO tripSchedule = tripScheduleService.queryById(scheduleId);
        if (tripSchedule != null){
            req.setProductName(tripSchedule.getName());
            req.setTripNumber(tripSchedule.getTripNumber());
            List<String> resourceInfo = new ArrayList<>();
            resourceInfo.add(tripSchedule.getName());
            req.setResourceInfo(resourceInfo);
        }
        req.setSaleUserId(order.getId());
        UserDTO userDTO = sysUserService.queryCacheUser(order.getCreateId());
        if (userDTO != null){
            req.setSaleUserName(userDTO.getFullName());
        }
        return req;
    }

    /**
     * 封装财务认款请求参数
     * @param item
     * @param collection
     * @param tripSchedule
     * @param order
     * @param userId
     * @return
     */
    private BillAddCollectionReq packBillAddCollectionReq(CustomOrderCollectionAddItemReq item, CustomizedOrderCollection collection, CustomizedTripScheduleDTO tripSchedule, CustomizedOrder order, Long userId) {
        BillAddCollectionReq addReq = new BillAddCollectionReq();
        addReq.setBillNumber(collection.getCollectionNumber());
        addReq.setBusinessType(SystemBusinessType.OUTBOUND_CUSTOMIZATION.getCode());
        addReq.setCollectionWayId(item.getCollectionWayId());
        addReq.setCollectionWayName(item.getCollectionWay());
        addReq.setCollectionTypeId(item.getCollectionTypeId());
        addReq.setCollectionTypeName(item.getCollectionType());
        addReq.setCollectionAmount(collection.getPaidInAmount());
        addReq.setCurrencyId(item.getCurrencyTypeId());
        addReq.setCurrencyName(item.getCurrencyType());
        addReq.setExchangeRate(item.getExchangeRate());
        addReq.setCollectionTime(collection.getGmtCreate());
        addReq.setCollectionVoucherJsonList(item.getCollectionVoucherJsonList());
        addReq.setSaleOrderNumber(order.getOrderNumber());
        addReq.setSaleOrderId(order.getId());
        addReq.setScheduleId(tripSchedule.getId());
        addReq.setProductNumber(tripSchedule.getTripNumber());
        addReq.setProductName(tripSchedule.getName());
        List<String> resourceInfo = new ArrayList<>();
        resourceInfo.add(tripSchedule.getName());
        addReq.setResourceInfo(resourceInfo);
        addReq.setSaleUserId(collection.getCreateId());
        UserDTO userDTO = sysUserService.queryCacheUser(collection.getCreateId());
        addReq.setSaleUserName(userDTO.getFullName());
        addReq.setSaleDeptId(userDTO.getDeptId());
        addReq.setUserId(userId);
        addReq.setTouristSource(order.getCustomerType());
        if (Objects.equals(order.getCustomerType(),2)){
            addReq.setBigClientId(order.getBigClientId());
            addReq.setBigClientName(order.getBigClientName());
        }
        return addReq;
    }


    /**
     * 再次確認
     *
     * @param req
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result confirm(CustomOrderCollectionConfirmReq req) {
        //获取收款记录
        QueryWrapper<CustomizedOrderCollection> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.lambda().eq(CustomizedOrderCollection::getId, req.getId());
        queryWrapper1.lambda().eq(CustomizedOrderCollection::getIsDeleted, 0);
        CustomizedOrderCollection dbCollection = orderCollectionMapper.selectOne(queryWrapper1);
        if (dbCollection == null || !Objects.equals(dbCollection.getStatus(), 5)) {
            //审批不通过才能再次确认
            throw new BusinessException(SystemError.CUSTOM_ORDER_4021);
        }
        //更新数据
        dbCollection.setModifiedId(req.getUserId());
        dbCollection.setRejectMsg(null);
        dbCollection.setStatus(2);
        boolean bl = updateById(dbCollection);
        if (!bl){
            throw new BusinessException(SystemError.SYS_437);
        }
        //对接财务再次确认
        BillOperateRefundReq req1 = new BillOperateRefundReq();
        req1.setBillNumber(dbCollection.getCollectionNumber());
        req1.setBusinessType(SystemBusinessType.OUTBOUND_CUSTOMIZATION.getCode());
        req1.setUserId(req.getUserId());
        Result result = billService.reConfirm(req1);
        if (result == null || !result.isSuccess()){
            throw new BusinessException(SystemError.SYS_437);
        }
        return Result.success();
    }


    /**
     * 银行优惠计算
     *
     * @param req
     * @return
     */
    @Override
    public Result<CustomOrderCollectionCalculationDTO> calculation(CustomOrderCollectionCalculationReq req){
        if (req.getItems().size() <= 0) {
            throw new BusinessException(SystemError.SYS_409);
        }
        MainDataCurrencyUpdateStatusReq hkdReq = new MainDataCurrencyUpdateStatusReq();
        hkdReq.setId(CurrencyIdCode.HKD.getCode());
        Result<MainDataCurrencyQueryDTO> hkdResult = iMainDataCurrencyService.query(hkdReq);
        if (!hkdResult.isSuccess() || hkdResult.getData() == null) {
            throw new BusinessException(SystemError.SYS_411);
        }
        MainDataCurrencyQueryDTO hkdDTO = hkdResult.getData();
        //总收款金额
        BigDecimal totalPaidInAmount = new BigDecimal(0);
        //总银行优惠基准金额
        BigDecimal totalTouristAmount = new BigDecimal(0);
        List<CustomOrderCollectionCalculationItemDTO> itemList = new ArrayList<>();
        for (CustomOrderCollectionCalculationItemReq item : req.getItems()) {
            //排除银行优惠计算
            if (Objects.equals(CollectionRefundWayIdCode.BANK_PREFERENCE.getCode(), item.getCollectionWayId())) {
                continue;
            }
            //收款金额
            BigDecimal paidInAmount = new BigDecimal(0);
            CustomOrderCollectionCalculationItemDTO calculationItem = EntityUtil.copy(item, CustomOrderCollectionCalculationItemDTO.class);
            if (Objects.equals(CurrencyIdCode.HKD.getCode(), item.getCurrencyTypeId())) {
                calculationItem.setCurrencyType(hkdDTO.getCurrencyName());
                calculationItem.setCurrencyTypeId(CurrencyIdCode.HKD.getCode());
                calculationItem.setCurrencyCode(hkdDTO.getCurrencyCode());
                paidInAmount = item.getCurrencyPaidInAmount();
            } else {
                //查询币种列表
                MainDataCurrencyUpdateStatusReq currencyUpdateStatusReq = new MainDataCurrencyUpdateStatusReq();
                currencyUpdateStatusReq.setId(item.getCurrencyTypeId());
                Result<MainDataCurrencyQueryDTO> currencyQueryDTOResult = iMainDataCurrencyService.query(currencyUpdateStatusReq);
                if (!currencyQueryDTOResult.isSuccess() || currencyQueryDTOResult.getData() == null) {
                    throw new BusinessException(SystemError.SYS_411);
                }
                MainDataCurrencyQueryDTO currencyQueryDTO = currencyQueryDTOResult.getData();
                calculationItem.setCurrencyType(currencyQueryDTO.getCurrencyName());
                calculationItem.setCurrencyTypeId(item.getCurrencyTypeId());
                calculationItem.setCurrencyCode(currencyQueryDTO.getCurrencyCode());
                //收款金额 港幣金額=其他貨幣金額×對應的門市匯率
                paidInAmount = item.getCurrencyPaidInAmount().multiply(currencyQueryDTO.getMarketExchangeRate());
            }

            QueryWrapper<CustomizedOrderTouristInfo> queryWrapper2 = new QueryWrapper<>();
            queryWrapper2.lambda().eq(CustomizedOrderTouristInfo::getOrderId, req.getOrderId());
            queryWrapper2.lambda().eq(CustomizedOrderTouristInfo::getId, item.getTouristId());
            queryWrapper2.lambda().eq(CustomizedOrderTouristInfo::getIsDeleted, IsDeletedCode.NO.getCode());
            CustomizedOrderTouristInfo touristInfo = orderTouristInfoMapper.selectOne(queryWrapper2);
            if (touristInfo == null) {
                throw new BusinessException(SystemError.SYS_411);
            }
            QueryWrapper<CustomizedOrderTouristFeeAdjust> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(CustomizedOrderTouristFeeAdjust::getTouristId, item.getTouristId());
            queryWrapper.lambda().eq(CustomizedOrderTouristFeeAdjust::getAdjustType, 1);
            queryWrapper.lambda().eq(CustomizedOrderTouristFeeAdjust::getIsDeleted, IsDeletedCode.NO.getCode());
            List<CustomizedOrderTouristFeeAdjust> feeAdjustList = orderTouristFeeAdjustMapper.selectList(queryWrapper);
            BigDecimal touristAmount = touristInfo.getGroupFee();
            for (CustomizedOrderTouristFeeAdjust feeAdjust : feeAdjustList) {
                if (Objects.equals(feeAdjust.getPlusType(), 1)) {
                    touristAmount = touristAmount.add(feeAdjust.getAmount());
                } else if (Objects.equals(feeAdjust.getPlusType(), 2)) {
                    touristAmount = touristAmount.subtract(feeAdjust.getAmount());
                }
            }
            //总收款金额
            totalPaidInAmount = totalPaidInAmount.add(paidInAmount);
            itemList.add(calculationItem);
            //总银行优惠基准金额
            totalTouristAmount = totalTouristAmount.add(touristAmount);
        }
        //查看并校验银联优惠
        Result<OperateBankPreferenceQueryDTO> preferenceQueryDTOResult = null;
        if (req.getBankPreferenceId() != null) {
            CustomOrderCollectionCalculationItemReq firstItem = req.getItems().get(0);
            OperateBankConformQueryReq bankPreferenceQueryReq = new OperateBankConformQueryReq();
            bankPreferenceQueryReq.setId(req.getBankPreferenceId());
            bankPreferenceQueryReq.setBusinessType(2);
            bankPreferenceQueryReq.setCardNumber(firstItem.getPayer());
            bankPreferenceQueryReq.setChannelId(12345678902L);
            bankPreferenceQueryReq.setRelationId(req.getScheduleId());
            bankPreferenceQueryReq.setUserId(req.getUserId());
            bankPreferenceQueryReq.setTotalPaidIn(totalTouristAmount);
            bankPreferenceQueryReq.setDiscountObjectId(12345678L);
            //TODO 参数未全
            preferenceQueryDTOResult = iOperateBankPreferenceService.queryConform(bankPreferenceQueryReq);
        }
        //总银行优惠金额
        BigDecimal totalBankPreferenceAmount = new BigDecimal(0);
        //银行优惠
        List<CustomOrderCollectionCalculationItemDTO> bankPreferenceList = new ArrayList<>();
        if (preferenceQueryDTOResult != null && preferenceQueryDTOResult.isSuccess() &&
                preferenceQueryDTOResult.getData() != null) {
            OperateBankPreferenceQueryDTO preferenceQueryDTOResultData = preferenceQueryDTOResult.getData();
            if (Objects.equals(preferenceQueryDTOResultData.getDiscountType(), NumberConstant.ONE.getValue())) {
                if (totalTouristAmount.compareTo(preferenceQueryDTOResultData.getFullAmount()) >= 0) {
                    BigDecimal bankPreference = totalTouristAmount.subtract(preferenceQueryDTOResultData.getReductionAmount());
                    totalBankPreferenceAmount = totalBankPreferenceAmount.add(bankPreference);
                }
            } else if (Objects.equals(preferenceQueryDTOResultData.getDiscountType(), NumberConstant.TWO.getValue())) {
                BigDecimal bankPreference = totalTouristAmount.subtract(totalTouristAmount.multiply(
                        BigDecimal.valueOf(preferenceQueryDTOResultData.getDiscountPercent())));
                if (bankPreference.compareTo(preferenceQueryDTOResultData.getMaxDiscount()) > 0) {
                    totalBankPreferenceAmount = totalBankPreferenceAmount.add(preferenceQueryDTOResultData.getMaxDiscount());
                } else {
                    totalBankPreferenceAmount = totalBankPreferenceAmount.add(bankPreference);
                }
            }
            int size = req.getItems().size();
            BigDecimal[] bankPreferenceAmount = totalBankPreferenceAmount.divideAndRemainder(new BigDecimal(size));
            MainDataFieldDataDTO collectionTypeDTO = iMainDataFieldDataService.queryFieldData(
                    CollectionTypeIdCode.FULL.getCode());
            if(collectionTypeDTO == null) {
                throw new BusinessException(SystemError.SYS_411);
            }
            //查詢收款退款方式
            MainDataPaymentRefundTypeIdReq bankReq = new MainDataPaymentRefundTypeIdReq();
            bankReq.setId(CollectionRefundWayIdCode.BANK.getCode());
            MainDataPaymentRefundTypeDTO bankDTO = iMainDataPaymentRefundTypeService.query(bankReq);
            if (bankDTO == null) {
                throw new BusinessException(SystemError.SYS_411);
            }
            MainDataPaymentRefundTypeIdReq bankPreferenceReq = new MainDataPaymentRefundTypeIdReq();
            bankPreferenceReq.setId(CollectionRefundWayIdCode.BANK_PREFERENCE.getCode());
            MainDataPaymentRefundTypeDTO bankPreferenceDTO = iMainDataPaymentRefundTypeService.query(bankPreferenceReq);
            if (bankPreferenceDTO == null) {
                throw new BusinessException(SystemError.SYS_411);
            }
            for (int i = 0; i < size; i++) {
                //添加项
                CustomOrderCollectionCalculationItemReq itemReq = req.getItems().get(i);
                itemReq.setCollectionTypeId(collectionTypeDTO.getId());
                itemReq.setCollectionType(collectionTypeDTO.getFieldValue());
                itemReq.setCollectionWayId(bankDTO.getId());
                itemReq.setCollectionWay(bankDTO.getPaymentRefundName());
                CustomOrderCollectionCalculationItemDTO bankPreferenceItem = EntityUtil.copy(itemReq, CustomOrderCollectionCalculationItemDTO.class);
                bankPreferenceItem.setCurrencyType(hkdDTO.getCurrencyName());
                bankPreferenceItem.setCurrencyTypeId(CurrencyIdCode.HKD.getCode());
                bankPreferenceItem.setCurrencyCode(hkdDTO.getCurrencyCode());
                bankPreferenceItem.setCollectionTypeId(collectionTypeDTO.getId());
                bankPreferenceItem.setCollectionType(collectionTypeDTO.getFieldValue());
                bankPreferenceItem.setCollectionWayId(bankPreferenceDTO.getId());
                bankPreferenceItem.setCollectionWay(bankPreferenceDTO.getPaymentRefundName());
                bankPreferenceItem.setCurrencyPaidInAmount(bankPreferenceAmount[0]);
                if (i == size - 1 && bankPreferenceAmount[1].compareTo(new BigDecimal(0)) > 0) {
                    bankPreferenceItem.setCurrencyPaidInAmount(bankPreferenceItem.getCurrencyPaidInAmount().add(bankPreferenceAmount[i]));
                }
                bankPreferenceItem.setPayer(null);
                bankPreferenceItem.setRemark(null);
                bankPreferenceItem.setCollectionVoucherNum(null);
                bankPreferenceItem.setCollectionVoucherJsonList(null);
                if(bankPreferenceItem.getCurrencyPaidInAmount().compareTo(new BigDecimal(0)) == 0) {
                    continue;
                }
                bankPreferenceList.add(bankPreferenceItem);
            }
        }
        itemList.addAll(bankPreferenceList);
        //返回数据
        CustomOrderCollectionCalculationDTO model = new CustomOrderCollectionCalculationDTO();
        model.setItemList(itemList);
        model.setTotalPaidInAmount(totalPaidInAmount);
        model.setTotalBankPreferenceAmount(totalBankPreferenceAmount);
        return Result.success(model);
    }


    /**
     * 调整项目
     *
     * @param req
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result adjustProject(CustomOrderAdjustProjectReq req) {
        //返回数据
        List<Long> result = new ArrayList<>();
        CustomizedOrder order = orderMapper.selectById(req.getOrderId());
        if (order == null || Objects.equals(order.getIsDeleted(),1)){
            throw new BusinessException(SystemError.CUSTOM_ORDER_4008);
        }
        //查询订单统计
        QueryWrapper<CustomizedOrderAmountStatistics> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_id",req.getOrderId());
        CustomizedOrderAmountStatistics statistics = orderAmountStatisticsMapper.selectOne(queryWrapper);
        if (statistics == null){
            throw new BusinessException(SystemError.CUSTOM_ORDER_4008);
        }
        List<CustomizedOrderTouristFeeAdjust> feeAdjustList = new ArrayList<>();
        List<Long> touristList = req.getIdList();
        //订单调整总费用
        BigDecimal totalAddAmount = BigDecimal.ZERO;
        BigDecimal totalReduceAmount = BigDecimal.ZERO;
        //旅客签证列表
        List<CustomizedOrderTouristVisa> touristVisaList = new ArrayList<>();
        for (Long touristId : touristList){
            CustomizedOrderTouristInfo touristInfo = orderTouristInfoMapper.selectById(touristId);
            if (touristInfo == null || Objects.equals(touristInfo.getIsDeleted(),NumberConstant.ONE.getValue())){
                throw new BusinessException(SystemError.CUSTOM_ORDER_4001);
            }
            //清空旧数据
        //    orderTouristFeeAdjustMapper.cleanByTourist(req.getOrderId(),touristId,req.getUserId());
            //旅客调整总费用
            BigDecimal touristAddAmount = BigDecimal.ZERO;
            BigDecimal touristReduceAmount = BigDecimal.ZERO;
            //增减团费
            List<FeeAdjustReq> feeAdjustIdList = req.getFeeAdjustList();
            if (feeAdjustIdList != null && feeAdjustIdList.size() > 0){
                for (FeeAdjustReq adjustReq : feeAdjustIdList){
                    //判断是否设置过该费用
                    if (checkFeeAdjust(req.getOrderId(),touristId,adjustReq.getMainDataId(),1)){
                        //封装调整费用属性
                        CustomizedOrderTouristFeeAdjust feeAdjust = saveTouristFeeAdjustParam(req.getOrderId(),req.getUserId(),1,touristId,
                                adjustReq.getProjectName(), adjustReq.getAdjustType(),adjustReq.getCostAmount(),adjustReq.getMainDataId());
                        feeAdjustList.add(feeAdjust);
                        result.add(feeAdjust.getId());
                        if (adjustReq.getAdjustType().intValue() == NumberConstant.ONE.getValue()){
                            touristAddAmount = touristAddAmount.add(adjustReq.getCostAmount());
                        }else{
                            touristReduceAmount = touristReduceAmount.add(adjustReq.getCostAmount());
                        }
                    }
                }
            }
            //签证
            List<VisaReq> visaList = req.getVisaIdList();
            if (visaList != null && visaList.size() > 0) {
                for (VisaReq visaReq : visaList) {
                    //判断是否设置过该费用
                    if (checkFeeAdjust(req.getOrderId(),touristId,visaReq.getVisaId(),2)){
                        CustomizedOrderTouristFeeAdjust feeAdjust = saveTouristFeeAdjustParam(req.getOrderId(),req.getUserId(),2,touristId,
                                visaReq.getName(), 1,visaReq.getAmount(),visaReq.getVisaId());
                        feeAdjustList.add(feeAdjust);
                        result.add(feeAdjust.getId());
                        touristAddAmount = touristAddAmount.add(visaReq.getAmount());
                        //新增旅客签证记录
                        CustomizedOrderTouristVisa visa = new CustomizedOrderTouristVisa();
                        visa.setId(SnowflakeIdWorker.nextId());
                        visa.setOrderId(req.getOrderId());
                        visa.setTouristId(touristId);
                        visa.setVisaAmount(visaReq.getAmount());
                        visa.setCollectionStatus(1);
                        visa.setNeedSupplyInfo(0);
                        visa.setSignOutStatus(3);
                        touristVisaList.add(visa);
                    }
                }
            }
            //更改资料
            List<ChangeRuleReq> ruleList = req.getRuleList();
            if (ruleList != null && ruleList.size() > 0){
                for (ChangeRuleReq ruleReq : ruleList){
                    //判断是否设置过该费用
                    if (checkFeeAdjust(req.getOrderId(),touristId,ruleReq.getMainDataId(),3)){
                        CustomizedOrderTouristFeeAdjust feeAdjust = saveTouristFeeAdjustParam(req.getOrderId(),req.getUserId(),3,touristId,
                                ruleReq.getName(), 1,ruleReq.getAmount(),ruleReq.getMainDataId());
                        feeAdjustList.add(feeAdjust);
                        result.add(feeAdjust.getId());
                        touristAddAmount = touristAddAmount.add(ruleReq.getAmount());
                    }
                }
            }
            //统计订单费用
            totalAddAmount = totalAddAmount.add(touristAddAmount);
            totalReduceAmount = totalReduceAmount.add(totalReduceAmount);
            //更新旅客金额统计
            BigDecimal touristAmount = BigDecimal.ZERO;
            if (touristAddAmount.compareTo(touristReduceAmount) > 0){
                //增加费用
                touristAmount = touristAddAmount.subtract(touristReduceAmount);
                touristInfo.setAdjustmentCost(touristInfo.getAdjustmentCost().add(touristAmount));
                touristInfo.setTotalReceivables(touristInfo.getTotalReceivables().add(touristAmount));
                touristInfo.setRemainingReceivables(touristInfo.getRemainingReceivables().add(touristAmount));
            }else if (touristAddAmount.compareTo(touristReduceAmount) < 0){
                //减少费用
                touristAmount = touristReduceAmount.subtract(touristAddAmount);
                touristInfo.setAdjustmentCost(touristInfo.getAdjustmentCost().subtract(touristAmount));
                touristInfo.setTotalReceivables(touristInfo.getTotalReceivables().subtract(touristAmount));
                touristInfo.setRemainingReceivables(touristInfo.getRemainingReceivables().subtract(touristAmount));
            }
            touristInfo.setModifiedId(req.getUserId());
            if (touristInfo.getRemainingReceivables().compareTo(BigDecimal.ZERO) > 0 && Objects.equals(touristInfo.getPayStatus(),3)){
                touristInfo.setPayStatus(2);
            }
            int update = orderTouristInfoMapper.updateById(touristInfo);
            if (update <= 0){
                throw new BusinessException(SystemError.SYS_437);
            }
        }
        if (feeAdjustList.size() > 0){
            //批量新增
            Integer batch = orderTouristFeeAdjustMapper.insertBatchSomeColumn(feeAdjustList);
            if (batch < feeAdjustList.size()){
                throw new BusinessException(SystemError.SYS_437);
            }
        }
        //批量新增旅客签证记录
        if (touristVisaList.size() > 0){
            Integer batch = orderTouristVisaMapper.insertBatchSomeColumn(touristVisaList);
            if (batch < touristVisaList.size()){
                throw new BusinessException(SystemError.SYS_437);
            }
        }
        //更新订单统计
        BigDecimal orderAmount = BigDecimal.ZERO;
        if (totalAddAmount.compareTo(totalReduceAmount) > 0){
            //增加费用
            orderAmount = totalAddAmount.subtract(totalReduceAmount);
            statistics.setAdjustmentCost(statistics.getAdjustmentCost().add(orderAmount));
            statistics.setTotalReceivables(statistics.getTotalReceivables().add(orderAmount));
            statistics.setRemainingReceivables(statistics.getRemainingReceivables().add(orderAmount));
        }else if (totalAddAmount.compareTo(totalReduceAmount) < 0){
            //减少费用
            orderAmount = totalReduceAmount.subtract(totalAddAmount);
            statistics.setAdjustmentCost(statistics.getAdjustmentCost().subtract(orderAmount));
            statistics.setTotalReceivables(statistics.getTotalReceivables().subtract(orderAmount));
            statistics.setRemainingReceivables(statistics.getRemainingReceivables().subtract(orderAmount));
        }
        //更新订单金额统计
        int update = orderAmountStatisticsMapper.updateById(statistics);
        if (update <= 0){
            throw new BusinessException(SystemError.SYS_437);
        }
        return Result.success(result);
    }


    /**
     * 封装调整费用属性
     * @return
     */
    private CustomizedOrderTouristFeeAdjust saveTouristFeeAdjustParam(Long orderId, Long userId, int adjustType, Long touristId,
                                                                      String name,int plusType,BigDecimal amount,Long relationId) {
        CustomizedOrderTouristFeeAdjust feeAdjust = new CustomizedOrderTouristFeeAdjust();
        feeAdjust.setId(SnowflakeIdWorker.nextId());
        feeAdjust.setOrderId(orderId);
        feeAdjust.setAdjustType(adjustType);
        feeAdjust.setTouristId(touristId);
        feeAdjust.setName(name);
        feeAdjust.setPlusType(plusType);
        feeAdjust.setAmount(amount);
        feeAdjust.setRelationId(relationId);
        feeAdjust.setCreateId(userId);
        feeAdjust.setGmtCreate(LocalDateTime.now());
        feeAdjust.setIsDeleted(0);
        return feeAdjust;
    }

    /**
     * 購買保險
     *
     * @param req
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<OrderBuyInsuranceDTO> buyInsurance(CustomOrderBuyInsuranceReq req) {
        OrderBuyInsuranceDTO orderBuyInsuranceDTO = new OrderBuyInsuranceDTO();
        List<BuyInsuranceDTO> dtoList = new ArrayList<>();
        CustomizedOrder order = orderMapper.selectById(req.getOrderId());
        if (order == null || Objects.equals(order.getIsDeleted(),NumberConstant.ONE.getValue())){
            throw new BusinessException(SystemError.CUSTOM_ORDER_4008);
        }
        List<CustomizedOrderInsurancePriceTourist> list = new ArrayList<>();
        //获取保险详情
        InsuranceDTO insuranceDTO = null;
        try {
            insuranceDTO = insuranceService.detail(req.getId());
        }catch (Exception e){
            throw new BusinessException(SystemError.CUSTOM_ORDER_4026);
        }
        if (insuranceDTO == null){
            throw new BusinessException(SystemError.CUSTOM_ORDER_4028);
        }
        //保险
        CustomizedOrderInsurance insurance = EntityUtil.copy(req,CustomizedOrderInsurance.class);
        insurance.setId(SnowflakeIdWorker.nextId());
        insurance.setOrderId(req.getOrderId());
        insurance.setScheduleId(order.getScheduleId());
        String insuranceNumber = numberService.getInsuranceNumber(req.getUserId());
        insurance.setInsuranceNumber(insuranceNumber);
        insurance.setInsuranceRecordId(insuranceDTO.getId());
        insurance.setMainDataId(req.getId());
        insurance.setName(insuranceDTO.getName());
        insurance.setApiCode(insuranceDTO.getApiCode());
        insurance.setRationType(insuranceDTO.getRationType());
        insurance.setInsuranceCarriers(insuranceDTO.getCompanyName());
        insurance.setCurrencyId(CurrencyIdCode.HKD.getCode());
        insurance.setCurrency(CurrencyIdCode.HKD.getMsg());
        insurance.setIsPay(0);
        insurance.setCreateId(req.getUserId());
        insurance.setIsDeleted(0);
        insurance.setIsPrint(0);
        //保险报价
        OfferDTO offerDTOS = insuranceOffer(req.getBeginDate(),req.getEndDate(),insuranceDTO.getRationType(),
                insuranceDTO.getApiCode(),req.getChildNum(),req.getAdultNum(),insuranceDTO.getId());
        insurance.setTotalAmount(offerDTOS.getPremium());
        List<Long> touristList = req.getTouristList();
        insurance.setPeopleNumber(touristList.size());
        //保险单价（各传1人获取单价）
        BigDecimal childPrice = BigDecimal.ZERO;
        BigDecimal adultPrice = BigDecimal.ZERO;
        if (req.getChildNum() > 0){
            OfferDTO offerChild = insuranceOffer(req.getBeginDate(),req.getEndDate(),insuranceDTO.getRationType(),
                    insuranceDTO.getApiCode(),1,0,insuranceDTO.getId());
            childPrice = offerChild.getPremium();
        }
        if (req.getAdultNum() > 0){
            OfferDTO offerAdult = insuranceOffer(req.getBeginDate(),req.getEndDate(),insuranceDTO.getRationType(),
                    insuranceDTO.getApiCode(),0,1,insuranceDTO.getId());
            adultPrice = offerAdult.getPremium();
        }
        //保险价格
        for (Long touristId : touristList){
            CustomizedOrderTouristInfo touristInfo = orderTouristInfoMapper.selectById(touristId);
            if (touristInfo == null || Objects.equals(touristInfo.getIsDeleted(),NumberConstant.ONE.getValue()) || Objects.equals(touristInfo.getBuyInsurance(),1)){
                throw new BusinessException(SystemError.CUSTOM_ORDER_4029);
            }
            //    touristInfo.setBuyInsurance(1);
            touristInfo.setInsuranceId(insurance.getId());
            touristInfo.setInsuranceName(insurance.getName());
            touristInfo.setModifiedId(req.getUserId());
            int update = orderTouristInfoMapper.updateById(touristInfo);
            if (update <= 0){
                throw new BusinessException(SystemError.SYS_437);
            }
            CustomizedOrderInsurancePriceTourist insurancePriceTourist = new CustomizedOrderInsurancePriceTourist();
            insurancePriceTourist.setId(SnowflakeIdWorker.nextId());
            insurancePriceTourist.setInsuranceId(insurance.getId());
            insurancePriceTourist.setOrderId(req.getOrderId());
            insurancePriceTourist.setScheduleId(order.getScheduleId());
            insurancePriceTourist.setTouristId(touristId);
            insurancePriceTourist.setTouristTypeId(touristInfo.getMainDataId());
            int age = touristInfo.getBirthday().until(LocalDate.now()).getYears();
            insurancePriceTourist.setAge(age);
            //获取年龄类型
            String ageType = PacificUtil.getAgeType(age);
            if (PacificAgeTypeCode.CHILD.getCode().equals(ageType)){
                //28:小童,太平保险那边固定的值
                insurancePriceTourist.setAmount(childPrice);
            }else{
                insurancePriceTourist.setAmount(adultPrice);
            }
            insurancePriceTourist.setEnSurname(touristInfo.getEnSurname());
            insurancePriceTourist.setEnName(touristInfo.getEnName());
            insurancePriceTourist.setBirthday(touristInfo.getBirthday());
            insurancePriceTourist.setSex(touristInfo.getGender());
            insurancePriceTourist.setCertificateTypeId(touristInfo.getCertificateTypeId());
            insurancePriceTourist.setCertificateNumber(touristInfo.getCertificateNumber());
            list.add(insurancePriceTourist);
            //返回数据
            BuyInsuranceDTO dto = new BuyInsuranceDTO();
            dto.setId(insurancePriceTourist.getId());
            dto.setTouristId(touristId);
            if (StringUtils.isNotBlank(touristInfo.getCnFullname())){
                dto.setTouristName(touristInfo.getCnFullname());
            }else if (StringUtils.isNotBlank(touristInfo.getEnFullname())){
                dto.setTouristName(touristInfo.getEnFullname());
            }
            dto.setCurrencyId(insurance.getCurrencyId());
            dto.setCurrency(insurance.getCurrency());
            dto.setAmount(insurancePriceTourist.getAmount());
            dtoList.add(dto);
        }
        int insert = orderInsuranceMapper.insert(insurance);
        //批量新增
        Integer batch = orderInsurancePriceTouristMapper.insertBatchSomeColumn(list);
        if (insert <= 0 || batch < list.size()){
            throw new BusinessException(SystemError.SYS_437);
        }
        //返回数据
        orderBuyInsuranceDTO.setInsuranceId(insurance.getId());
        orderBuyInsuranceDTO.setList(dtoList);
        return Result.success(orderBuyInsuranceDTO);
    }

    /**
     * 保险报价
     * @param beginDate
     * @param endDate
     * @param rationType
     * @param apiCode
     * @param childNum
     * @param adultNum
     * @return
     */
    public OfferDTO insuranceOffer(LocalDate beginDate, LocalDate endDate, Integer rationType, String apiCode, Integer childNum, Integer adultNum,Long insuranceId) {
        //请求参数
        OfferReq offerReq = new OfferReq();
        Offer offer = new Offer();
        offer.setStarDate(DateUtil.fmtLocalDate(beginDate,"yyyy-MM-dd"));
        offer.setEndDate(DateUtil.fmtLocalDate(endDate,"yyyy-MM-dd"));
        offer.setRationType(rationType);
        offer.setRiskCode(apiCode);
        offer.setChildCount((long)childNum);
        offer.setPersonCount((long)adultNum);
        offer.setInsuranceId(insuranceId);
        offerReq.setData(offer);
        OfferDTO offerDTOS = null;
        try {
            offerDTOS = insuranceService.acciQuotation(offerReq);
        }catch (Exception e){
            throw new BusinessException(SystemError.CUSTOM_ORDER_4026);
        }
        if (offerDTOS == null){
            throw new BusinessException(SystemError.CUSTOM_ORDER_4026);
        }
        return offerDTOS;
    }

    /**
     * 保險收款
     *
     * @param req
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result collectInsurance(CustomOrderCollectInsuranceReq req) {
        CustomizedOrder order = orderMapper.selectById(req.getOrderId());
        if (order == null || Objects.equals(order.getIsDeleted(),NumberConstant.ONE.getValue())){
            throw new BusinessException(SystemError.CUSTOM_ORDER_4008);
        }
        CustomizedTripScheduleDTO tripSchedule = tripScheduleService.queryByScheduleId(order.getScheduleId());
        //保单
        CustomizedOrderInsurance insurance = orderInsuranceMapper.selectById(req.getInsuranceId());
        if (insurance == null || Objects.equals(insurance.getIsDeleted(),NumberConstant.ONE.getValue())){
            throw new BusinessException(SystemError.CUSTOM_ORDER_4023);
        }
        if (insurance.getIsPay().intValue() == NumberConstant.ONE.getValue()){
            //重复收款
            throw new BusinessException(SystemError.CUSTOM_ORDER_4023);
        }
        //判断是否可以收款
        QueryWrapper<CustomizedOrderAmountStatistics> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(CustomizedOrderAmountStatistics::getOrderId, req.getOrderId());
        CustomizedOrderAmountStatistics statistics = orderAmountStatisticsMapper.selectOne(queryWrapper);
        //本次收款总金额
        List<OrderCollectionSumReq> reqList = EntityUtil.copyList(req.getItems(),OrderCollectionSumReq.class);
        OrderCollectionSumDTO sumDTO = iMainDataCurrencyService.orderCollectionSum(reqList);
        if (sumDTO == null){
            throw new BusinessException(SystemError.SYS_409,"幣種");
        }
        BigDecimal totalReciveAmount = sumDTO.getTotalAmount();
        //设置本位币金额
        for (CustomOrderCollectionAddItemReq item : req.getItems()) {
            for (OrderCollectionSumReq temp : sumDTO.getItemList()) {
                if (Objects.equals(item.getTouristId(),temp.getTouristId())){
                    item.setHkdAmount(temp.getHkdAmount());
                    break;
                }
            }
        }
       /* if (totalReciveAmount.compareTo(statistics.getRemainingReceivables()) > 0){
            throw new BusinessException(SystemError.CUSTOM_ORDER_4009);
        }*/
        //收据金额
        BigDecimal totalAmount = BigDecimal.ZERO;
        List<CustomizedOrderCollection> collectionList = new ArrayList<>();
        List<CustomizedOrderReceiptTourist> receiptTouristList = new ArrayList<>();
        //订单收据
        CustomizedOrderReceipt receipt = new CustomizedOrderReceipt();
        receipt.setId(SnowflakeIdWorker.nextId());
        receipt.setOrderId(req.getOrderId());
        receipt.setScheduleId(order.getScheduleId());
        receipt.setReceiptAmount(totalReciveAmount);
        //收据单号
        String receiptNumber = numberService.getReceiptNumber(req.getUserId());
        receipt.setReceiptNumber(receiptNumber);
        receipt.setReceiptType(2);
        receipt.setCreateTime(LocalDateTime.now());
        receipt.setReceiptStatus(1);
        receipt.setCreateId(req.getUserId());
        receipt.setIsDeleted(0);

        //新增财务认款请求参数
        List<BillAddCollectionReq> addListReq = new ArrayList<>();

        //印花税金额
        BigDecimal stampDutyAmount = BigDecimal.ZERO;
        //调整费用列表
        List<CustomizedOrderTouristFeeAdjust> feeAdjustList = new ArrayList<>();
        List<CustomOrderCollectionAddItemReq> itemList = req.getItems();
        for (CustomOrderCollectionAddItemReq itemReq : itemList){
            //计算印花税
            stampDutyAmount = stampDutyAmount.add(itemReq.getPaidInAmount().multiply(new BigDecimal(Constants.STAMP_DUTY_RATIO)));
            //更新旅客金额
            CustomizedOrderTouristInfo touristInfo = orderTouristInfoMapper.selectById(itemReq.getTouristId());
            if (touristInfo.getRemainingReceivables().compareTo(itemReq.getPaidInAmount()) < 0){
                continue;
            }
            touristInfo.setBuyInsurance(1);
            touristInfo.setTotalReceivables(touristInfo.getTotalReceivables().add(itemReq.getPaidInAmount()));
            touristInfo.setTotalPaidIn(touristInfo.getTotalPaidIn().add(itemReq.getPaidInAmount()));
       //     touristInfo.setRemainingReceivables(touristInfo.getRemainingReceivables().subtract(itemReq.getPaidInAmount()));
            touristInfo.setReceiptedAmount(touristInfo.getReceiptedAmount().add(totalReciveAmount));
            touristInfo.setModifiedId(req.getUserId());
            if (touristInfo.getRemainingReceivables().compareTo(BigDecimal.ZERO) <= 0){
                //已付全款
                touristInfo.setPayStatus(3);
            }
            int update = orderTouristInfoMapper.updateById(touristInfo);
            if (update <= 0){
                throw new BusinessException(SystemError.SYS_437);
            }
            //收款记录
            CustomizedOrderCollection collection = EntityUtil.copy(itemReq, CustomizedOrderCollection.class);
            LocalDateTime now = LocalDateTime.now();
            collection.setId(SnowflakeIdWorker.nextId());
        //    BigDecimal hkdAmount = iMainDataCurrencyService.getHkdAmount(itemReq.getCurrencyTypeId(), itemReq.getPaidInAmount());
            collection.setCurrencyPaidInAmount(itemReq.getPaidInAmount());
            collection.setPaidInAmount(itemReq.getHkdAmount());
            collection.setPayerId(req.getPayerId());
            collection.setGmtCreate(now);
            collection.setIsDeleted(0);
            collection.setCreateId(req.getUserId());
            collection.setIsPos(req.getIsPos());
            //收款单号
            String collectionNumber = numberService.getCollectionNumber();
            collection.setCollectionNumber(collectionNumber);
            collection.setStatus(2);
            collection.setOrderId(req.getOrderId());
            collection.setScheduleId(order.getScheduleId());
            collection.setIsPrint(1);
            collectionList.add(collection);
            //财务认款请求参数
            BillAddCollectionReq addReq = packBillAddCollectionReq(itemReq,collection,tripSchedule,order,req.getUserId());
            addListReq.add(addReq);
            //收据关联旅客
            CustomizedOrderReceiptTourist receiptTourist = new CustomizedOrderReceiptTourist();
            receiptTourist.setId(SnowflakeIdWorker.nextId());
            receiptTourist.setReceiptId(receipt.getId());
            receiptTourist.setOrderId(req.getOrderId());
            receiptTourist.setTouristId(itemReq.getTouristId());
            receiptTourist.setCreateId(req.getUserId());
            receiptTourist.setReceiptAmount(collection.getPaidInAmount());
            receiptTourist.setIsDeleted(0);
            receiptTouristList.add(receiptTourist);
            totalAmount = totalAmount.add(collection.getPaidInAmount());
            //新增调整费用
            CustomizedOrderTouristFeeAdjust feeAdjust = new CustomizedOrderTouristFeeAdjust();
            feeAdjust.setId(SnowflakeIdWorker.nextId());
            feeAdjust.setOrderId(order.getId());
            feeAdjust.setAdjustType(4);
            feeAdjust.setTouristId(touristInfo.getId());
            feeAdjust.setName("保險");
            feeAdjust.setPlusType(1);
            feeAdjust.setAmount(collection.getPaidInAmount());
            feeAdjust.setRelationId(collection.getId());
            feeAdjust.setCreateId(req.getUserId());
            feeAdjust.setGmtCreate(now);
            feeAdjust.setIsDeleted(0);
            feeAdjustList.add(feeAdjust);
        }
        //更新订单统计
        statistics.setTotalReceivables(statistics.getTotalReceivables().add(totalAmount));
        statistics.setTotalPaidIn(statistics.getTotalPaidIn().add(totalAmount));
        statistics.setReceiptedAmount(statistics.getReceiptedAmount().add(totalAmount));
        int update1 = orderAmountStatisticsMapper.updateById(statistics);
        if (update1 <= 0){
            throw new BusinessException(SystemError.SYS_437);
        }
        //收据
        receipt.setReceiptHeader(insurance.getPolicyHolderName());
        receipt.setReceiptAmount(totalAmount);
        receipt.setIncludeTouristNum(itemList.size());
        //新增订单收据
        int insertReceipt = orderReceiptMapper.insert(receipt);
        //批量新增调整费用
        if (feeAdjustList.size() > 0){
            Integer batch = orderTouristFeeAdjustMapper.insertBatchSomeColumn(feeAdjustList);
            if (batch < feeAdjustList.size()){
                throw new BusinessException(SystemError.SYS_437);
            }
        }
        //批量新增收据关联旅客
        if (receiptTouristList.size() > 0){
            Integer batch = orderReceiptTouristMapper.insertBatchSomeColumn(receiptTouristList);
            if (insertReceipt <= 0 || batch < receiptTouristList.size()){
                throw new BusinessException(SystemError.SYS_437);
            }
        }
        //批量新增收款
        if (collectionList.size() > 0){
            Integer batch = orderCollectionMapper.insertBatchSomeColumn(collectionList);
            if (batch < collectionList.size()){
                throw new BusinessException(SystemError.SYS_437);
            }
        }
        //直接生成保单收据
        ReceiptInsuranceAddReq addReq = EntityUtil.copy(req,ReceiptInsuranceAddReq.class);
        addReq.setCurrency(CurrencyIdCode.HKD.getMsg());
        addReq.setCardNumber(req.getPayer());
        Long insuranceReceiptId = orderReceiptInsuranceService.createInsuranceReceipt(addReq);
        if (insuranceReceiptId == null){
            throw new BusinessException(SystemError.SYS_437);
        }
        //调用保险API
        InsuranceInsuredDTO insuranceInsuredDTO = null;
        //封装参保请求参数
        InsuranceUnderwritingReq insuranceUnderwritingReq = new InsuranceUnderwritingReq();
        List<AcceptUnderReq> acceptReq = packJoinInsuranceReq(insurance);
        insuranceUnderwritingReq.setAcceptReqList(acceptReq);
        insuranceUnderwritingReq.setUserId(req.getUserId());
        insuranceUnderwritingReq.setInsuranceId(insurance.getInsuranceRecordId());
        insuranceUnderwritingReq.setOrderNumber(order.getOrderNumber());
        insuranceUnderwritingReq.setBusinessType(SystemBusinessType.OUTBOUND_CUSTOMIZATION.getCode());
        insuranceUnderwritingReq.setTotalFee(insurance.getTotalAmount());
        try {
            insuranceInsuredDTO = insuranceService.sendProposalContent(insuranceUnderwritingReq);
        }catch (Exception e){
            throw new BusinessException(SystemError.CUSTOM_ORDER_4026);
        }
        List<AcceptDTO> acceptDTOS = insuranceInsuredDTO.getAcceptDTOS();
        if (insuranceInsuredDTO == null || acceptDTOS == null || acceptDTOS.size() == 0){
            throw new BusinessException(SystemError.CUSTOM_ORDER_4026);
        }
        //参保记录
        List<CustomizedOrderInsuranceJoin> joinList = new ArrayList<>();
        for (AcceptDTO acceptDTO : acceptDTOS){
            CustomizedOrderInsuranceJoin join = EntityUtil.copy(acceptDTO, CustomizedOrderInsuranceJoin.class);
            join.setId(SnowflakeIdWorker.nextId());
            join.setInsuranceId(req.getInsuranceId());
            join.setOrderId(req.getOrderId());
            join.setScheduleId(order.getScheduleId());
            join.setCreateId(req.getUserId());
            join.setGmtCreate(LocalDateTime.now());
            join.setIsDeleted(0);
            joinList.add(join);
        }
        if(joinList.size() > 0){
            Integer batchJoin = orderInsuranceJoinMapper.insertBatchSomeColumn(joinList);
            if (batchJoin < joinList.size()){
                throw new BusinessException(SystemError.SYS_437);
            }
        }
        //更新保单状态
        insurance.setReceiptId(receipt.getId());
        insurance.setIsPay(1);
        insurance.setModifiedId(req.getUserId());
        int updateInsurance = orderInsuranceMapper.updateById(insurance);
        if (updateInsurance <= 0){
            throw new BusinessException(SystemError.SYS_437);
        }
        CustomizedOrderReceiptInsurance receiptInsurance = orderReceiptInsuranceMapper.selectById(insuranceReceiptId);
        //印花税金额
        receiptInsurance.setStampDutyAmount(insuranceInsuredDTO.getStampDutyAmount());
        receiptInsurance.setStampDutyPic(insuranceInsuredDTO.getStampDutyPic());
        receiptInsurance.setInsuranceNumber(insuranceInsuredDTO.getInsuranceReceiptNumber());
        //更新保单收据
        int updateById = orderReceiptInsuranceMapper.updateById(receiptInsurance);
        if (updateById <= 0){
            throw new BusinessException(SystemError.SYS_437);
        }
        //对接财务认款
        Result result = billService.addCollection(addListReq);
        if (result == null || !result.isSuccess()){
            throw new BusinessException(SystemError.SYS_437);
        }
        return Result.success(receipt.getId());
    }


    /**
     * 验证优惠
     *
     * @param req
     * @return
     */
    @Override
    public Result<CustomOrderVerifyPromotionDTO> verifyDiscount(CustomOrderVerifyDiscountReq req){
        BigDecimal totalAmount = new BigDecimal(0);
        Map<Long, BigDecimal> map = new HashMap<>();
        for (Long touristId : req.getTouristIdList()) {
            //获取旅客
            QueryWrapper<CustomizedOrderTouristInfo> queryWrapper2 = new QueryWrapper<>();
            queryWrapper2.lambda().eq(CustomizedOrderTouristInfo::getOrderId, req.getOrderId());
            queryWrapper2.lambda().eq(CustomizedOrderTouristInfo::getId, touristId);
            queryWrapper2.lambda().eq(CustomizedOrderTouristInfo::getIsDeleted, IsDeletedCode.NO.getCode());
            CustomizedOrderTouristInfo touristInfo = orderTouristInfoMapper.selectOne(queryWrapper2);
            if (touristInfo == null) {
                throw new BusinessException(SystemError.CUSTOM_ORDER_4001);
            }
            //调整费用
            QueryWrapper<CustomizedOrderTouristFeeAdjust> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(CustomizedOrderTouristFeeAdjust::getTouristId, touristId);
            queryWrapper.lambda().eq(CustomizedOrderTouristFeeAdjust::getAdjustType, 1);
            queryWrapper.lambda().eq(CustomizedOrderTouristFeeAdjust::getIsDeleted, IsDeletedCode.NO.getCode());
            List<CustomizedOrderTouristFeeAdjust> feeAdjustList = orderTouristFeeAdjustMapper.selectList(queryWrapper);
            BigDecimal touristAmount = touristInfo.getGroupFee();
            for (CustomizedOrderTouristFeeAdjust feeAdjust : feeAdjustList) {
                if (Objects.equals(feeAdjust.getPlusType(), NumberConstant.ONE.getValue())) {
                    //加
                    touristAmount = touristAmount.add(feeAdjust.getAmount());
                } else if (Objects.equals(feeAdjust.getPlusType(), NumberConstant.TWO.getValue())) {
                    //减
                    touristAmount = touristAmount.subtract(feeAdjust.getAmount());
                }
            }
            totalAmount = totalAmount.add(touristAmount);
            map.put(touristId, touristAmount);
        }
        //根据优惠码查询推广码
        OperatePromotionConformReq operatePromotionConformReq = new OperatePromotionConformReq();
        operatePromotionConformReq.setActivityCode(req.getActivityCode());
        operatePromotionConformReq.setBusinessType(2);
        operatePromotionConformReq.setRelationId(req.getScheduleId());
        operatePromotionConformReq.setUserId(req.getUserId());
        operatePromotionConformReq.setTotalPaidIn(totalAmount);
        //TODO 参数未全
        operatePromotionConformReq.setDiscountObjectId(12345678L);
        operatePromotionConformReq.setChannelId(12345678902L);
        Result<OperatePromotionQueryDTO> promotionQueryDTOResult = iOperatePromotionService.queryConform(operatePromotionConformReq);
        //是否有效
        int isEffective = ISCode.NO.getCode();
        //有效数量
        int effectiveNum = 0;
        //减免金额
        BigDecimal reductionAmount = new BigDecimal(0);
        CustomOrderVerifyPromotionDTO dto = new CustomOrderVerifyPromotionDTO();
        if (promotionQueryDTOResult.isSuccess() && promotionQueryDTOResult.getData() != null) {
            OperatePromotionQueryDTO promotionQueryDTO = promotionQueryDTOResult.getData();
            dto.setDiscountId(promotionQueryDTO.getId());
            for (Long touristId : req.getTouristIdList()) {
                BigDecimal touristAmount = map.get(touristId);
                if (touristAmount.compareTo(promotionQueryDTO.getFullAmount()) >= 0) {
                    isEffective = ISCode.YES.getCode();
                    effectiveNum ++;
                }
            }
            reductionAmount = promotionQueryDTO.getReductionAmount();
        }
        dto.setReductionAmount(reductionAmount);
        dto.setIsEffective(isEffective);
        dto.setEffectiveNum(effectiveNum);
        return Result.success(dto);
    }


    /**
     * 使用优惠
     *
     * @param req
     * @param currentUser
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result useDiscount(CustomOrderUseDiscountReq req, TokenUser currentUser) {
        //查询推广码详情
        OperatePromotionQueryReq operatePromotionQueryReq = new OperatePromotionQueryReq();
        operatePromotionQueryReq.setId(req.getDiscountId());
        Result<OperatePromotionQueryDTO> operatePromotionQueryDTOResult = iOperatePromotionService.query(operatePromotionQueryReq);
        if (!operatePromotionQueryDTOResult.isSuccess() || operatePromotionQueryDTOResult.getData() == null) {
            throw new BusinessException(SystemError.SYS_411);
        }
        //收款类型主数据
        OperatePromotionQueryDTO promotionQueryDTO = operatePromotionQueryDTOResult.getData();
        MainDataFieldDataDTO collectionTypeDTO = iMainDataFieldDataService.queryFieldData(CollectionTypeIdCode.OTHER.getCode());
        if(collectionTypeDTO == null) {
            throw new BusinessException(SystemError.SYS_411);
        }
        //查询币种列表
        MainDataCurrencyUpdateStatusReq currencyUpdateStatusReq = new MainDataCurrencyUpdateStatusReq();
        currencyUpdateStatusReq.setId(CurrencyIdCode.HKD.getCode());
        Result<MainDataCurrencyQueryDTO> currencyQueryDTOResult = iMainDataCurrencyService.query(currencyUpdateStatusReq);
        if (!currencyQueryDTOResult.isSuccess() || currencyQueryDTOResult.getData() == null) {
            throw new BusinessException(SystemError.SYS_411);
        }
        MainDataCurrencyQueryDTO currencyQueryDTO = currencyQueryDTOResult.getData();
        //查詢收款退款方式
        MainDataPaymentRefundTypeIdReq operatePromotionReq = new MainDataPaymentRefundTypeIdReq();
        operatePromotionReq.setId(CollectionRefundWayIdCode.OPERATE_PROMOTION.getCode());
        MainDataPaymentRefundTypeDTO operatePromotionDTO = iMainDataPaymentRefundTypeService.query(operatePromotionReq);
        if (operatePromotionDTO == null) {
            throw new BusinessException(SystemError.SYS_411);
        }
        List<CustomizedOrderCollection> collectionList = new ArrayList<>();
        //优惠金额
        BigDecimal totalDiscountAmount = new BigDecimal(0);
        for (Long touristId : req.getTouristIdList()) {
            QueryWrapper<CustomizedOrderCollection> queryWrapper4 = new QueryWrapper<>();
            queryWrapper4.lambda().eq(CustomizedOrderCollection::getOrderId, req.getOrderId());
            queryWrapper4.lambda().eq(CustomizedOrderCollection::getTouristId, touristId);
            queryWrapper4.lambda().eq(CustomizedOrderCollection::getCollectionWayId, CollectionRefundWayIdCode.OPERATE_PROMOTION.getCode());
            queryWrapper4.lambda().eq(CustomizedOrderCollection::getIsDeleted, IsDeletedCode.NO.getCode());
            Integer discountCount = orderCollectionMapper.selectCount(queryWrapper4);
            if(discountCount > 0) {
                continue;
            }
            //旅客信息
            QueryWrapper<CustomizedOrderTouristInfo> queryWrapper2 = new QueryWrapper<>();
            queryWrapper2.lambda().eq(CustomizedOrderTouristInfo::getOrderId, req.getOrderId());
            queryWrapper2.lambda().eq(CustomizedOrderTouristInfo::getId, touristId);
            queryWrapper2.lambda().eq(CustomizedOrderTouristInfo::getIsDeleted, IsDeletedCode.NO.getCode());
            CustomizedOrderTouristInfo touristInfo = orderTouristInfoMapper.selectOne(queryWrapper2);
            if (touristInfo == null) {
                throw new BusinessException(SystemError.SYS_411);
            }
            QueryWrapper<CustomizedOrderTouristFeeAdjust> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(CustomizedOrderTouristFeeAdjust::getTouristId, touristId);
            queryWrapper.lambda().eq(CustomizedOrderTouristFeeAdjust::getAdjustType, 1);
            queryWrapper.lambda().eq(CustomizedOrderTouristFeeAdjust::getIsDeleted, IsDeletedCode.NO.getCode());
            List<CustomizedOrderTouristFeeAdjust> feeAdjustList = orderTouristFeeAdjustMapper.selectList(queryWrapper);
            BigDecimal touristAmount = touristInfo.getGroupFee();
            for (CustomizedOrderTouristFeeAdjust feeAdjust : feeAdjustList) {
                if (Objects.equals(feeAdjust.getPlusType(), NumberConstant.ONE.getValue())) {
                    touristAmount = touristAmount.add(feeAdjust.getAmount());
                } else if (Objects.equals(feeAdjust.getPlusType(), NumberConstant.TWO.getValue())) {
                    touristAmount = touristAmount.subtract(feeAdjust.getAmount());
                }
            }
            if (touristAmount.compareTo(promotionQueryDTO.getFullAmount()) >= 0) {
                BigDecimal discountAmount = touristAmount.subtract(promotionQueryDTO.getReductionAmount());
                //新增收款记录
                CustomizedOrderCollection collection = new CustomizedOrderCollection();
                LocalDateTime now = LocalDateTime.now();
                collection.setId(IdWorker.getId());
                collection.setGmtCreate(now);
                collection.setIsDeleted(IsDeletedCode.NO.getCode());
                collection.setGmtModified(now);
                collection.setCreateId(req.getUserId());
                collection.setModifiedId(req.getUserId());
                collection.setIsPos(0);
                collection.setCollectionNumber(numberService.getCollectionNumber());
                collection.setStatus(2);
                collection.setOrderId(req.getOrderId());
                collection.setScheduleId(req.getScheduleId());
                collection.setIsPrint(ISCode.NO.getCode());
                collection.setPaidInAmount(discountAmount);
                collection.setCurrencyPaidInAmount(discountAmount);
                collection.setCurrencyType(currencyQueryDTO.getCurrencyName());
                collection.setCurrencyTypeId(CurrencyIdCode.HKD.getCode());
                collection.setCollectionTypeId(collectionTypeDTO.getId());
                collection.setCollectionType(collectionTypeDTO.getFieldValue());
                collection.setCollectionWayId(operatePromotionDTO.getId());
                collection.setCollectionWay(operatePromotionDTO.getPaymentRefundName());
                RelationInfoJsonBankPreference relationInfoJson = new RelationInfoJsonBankPreference();
                relationInfoJson.setDiscountId(req.getDiscountId());
                relationInfoJson.setDiscountType(1);
                collection.setRelationInfoJson(JSON.toJSONString(relationInfoJson));
                collectionList.add(collection);
                //游客统计
                touristInfo.setTotalPaidIn(touristInfo.getTotalPaidIn().add(collection.getPaidInAmount()));
                touristInfo.setRemainingReceivables(touristInfo.getRemainingReceivables().subtract(collection.getPaidInAmount()));
                if(touristInfo.getTotalPaidIn().compareTo(touristInfo.getTotalReceivables()) == 0){
                    //已付全款
                    touristInfo.setPayStatus(3);
                } else if(touristInfo.getTotalPaidIn().compareTo(new BigDecimal(0)) > 0 &&
                        touristInfo.getTotalPaidIn().compareTo(touristInfo.getTotalReceivables()) < 0){
                    //待付余款
                    touristInfo.setPayStatus(2);
                }
                int update = orderTouristInfoMapper.updateById(touristInfo);
                if (update <= 0){
                    throw new BusinessException(SystemError.SYS_437);
                }
                //订单统计
                QueryWrapper<CustomizedOrderAmountStatistics> queryWrapper3 = new QueryWrapper<>();
                queryWrapper3.lambda().eq(CustomizedOrderAmountStatistics::getOrderId, collection.getOrderId());
                CustomizedOrderAmountStatistics statistics = orderAmountStatisticsMapper.selectOne(queryWrapper3);
                statistics.setTotalPaidIn(statistics.getTotalPaidIn().add(collection.getPaidInAmount()));
                statistics.setRemainingReceivables(statistics.getRemainingReceivables().subtract(collection.getPaidInAmount()));
                int update1 = orderAmountStatisticsMapper.updateById(statistics);
                if (update1 <= 0){
                    throw new BusinessException(SystemError.SYS_437);
                }
                //优惠金额
                totalDiscountAmount = totalDiscountAmount.add(discountAmount);
            }
        }
        //批量新增收款记录
        if (collectionList.size() > 0){
            boolean bl = saveBatch(collectionList);
            if (!bl){
                throw new BusinessException(SystemError.SYS_437);
            }
        }
        //扣减推广码剩余名额及剩余金额
        OperatePromotionDeductReq operatePromotionDeductReq = new OperatePromotionDeductReq();
        operatePromotionDeductReq.setId(req.getDiscountId());
        operatePromotionDeductReq.setBusinessType(2);
        operatePromotionDeductReq.setTotalPaidIn(totalDiscountAmount);
        operatePromotionDeductReq.setRelationId(req.getScheduleId());
        //TODO 参数未全
        operatePromotionDeductReq.setChannelId(12345678902L);
        operatePromotionDeductReq.setDiscountObjectId(12345678L);
        Result result = iOperatePromotionService.deduct(operatePromotionDeductReq, currentUser);
        if (!result.isSuccess()) {
            throw new BusinessException(SystemError.CUSTOM_ORDER_4025);
        }
        return Result.success();
    }


    /**
     * 可购买保险列表
     *
     * @param req
     * @return
     */
    @Override
    public Result<List<OrderInsuranceDTO>> insuranceList(CustomOrderInsuranceListReq req) {
        List<OrderInsuranceDTO> list = new ArrayList<>();
        List<TripScheduleInsuranceDTO> insuranceList =  tripScheduleService.getInsuranceList(req.getScheduleId());
        if (insuranceList != null && insuranceList.size() > 0){
            //旅客信息
            int childNum = 0;
            int adultNum = 0;
            List<Long> touristList = req.getTouristList();
            for (Long touristId : touristList){
                CustomizedOrderTouristInfo touristInfo = orderTouristInfoMapper.selectById(touristId);
                if (touristInfo != null){
                    Integer age = DateUtil.getAge(touristInfo.getBirthday());
                    String ageType = PacificUtil.getAgeType(age);
                    if (PacificAgeTypeCode.CHILD.getCode().equals(ageType)){
                        childNum++;
                    }else{
                        adultNum++;
                    }
                }
            }
            //获取报价
            try {
                for (TripScheduleInsuranceDTO insuranceDTO : insuranceList){
                    InsuranceDTO detail = insuranceService.detail(insuranceDTO.getId());
                    if (detail != null){
                        OrderInsuranceDTO dto = EntityUtil.copy(detail,OrderInsuranceDTO.class);
                        OfferDTO offerDTO = insuranceOffer(req.getBeginDate(), req.getEndDate(), detail.getRationType(), detail.getApiCode(), childNum, adultNum,insuranceDTO.getId());
                        if (offerDTO != null){
                            dto.setTotalAmount(offerDTO.getPremium());
                            dto.setChildNum(childNum);
                            dto.setAdultNum(adultNum);
                        }
                        list.add(dto);
                    }
                }
            }catch (Exception e){
                throw new BusinessException(SystemError.CUSTOM_ORDER_4026);
            }
        }
        return Result.success(list);
    }

    /**
     * 更新关联收款记录是否开收据状态
     *
     * @param receiptId
     * @param orderId
     * @param userId
     */
    @Override
    public void batchUpdateIsPrint(Long receiptId, Long orderId, Long userId) {
        //获取该收据关联的收款记录
        QueryWrapper<CustomizedOrderCollection> collectionQueryWrapper = new QueryWrapper<>();
        collectionQueryWrapper.eq("receipt_id",receiptId);
        collectionQueryWrapper.eq("order_id",orderId);
        collectionQueryWrapper.eq("status",3);
        collectionQueryWrapper.eq("is_deleted",0);
        List<CustomizedOrderCollection> collectionList = orderCollectionMapper.selectList(collectionQueryWrapper);
        if (collectionList != null && collectionList.size() > 0){
            collectionList.forEach(collection -> {
                collection.setIsPrint(0);
                collection.setModifiedId(userId);
            });
            updateBatchById(collectionList);
        }
    }

    /**
     * 审核
     *
     * @param req
     * @return
     */
    @Override
    public Result approval(CustomOrderCollectionApprovalReq req) {
        //获取收款记录
        CustomizedOrderCollection collection = getById(req.getId());
        if (collection == null){
            throw new BusinessException(SystemError.CUSTOM_ORDER_4047);
        }
        //状态判断
        if (!Objects.equals(collection.getStatus(),NumberConstant.TWO.getValue())){
            throw new BusinessException(SystemError.CUSTOM_ORDER_4048);
        }
        //更新
        collection.setStatus(req.getStatus());
        collection.setModifiedId(req.getUserId());
        collection.setRejectMsg(req.getRejectMsg());
        boolean bl = updateById(collection);
        if (!bl){
            throw new BusinessException(SystemError.SYS_437);
        }
        return Result.success(collection.getId());
    }

    /**
     * 驳回
     *
     * @param collectionNumber 收款单号
     * @param rejectInfo       驳回信息
     * @param userId 用户ID
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result reject(String collectionNumber, String rejectInfo,Long userId) {
        QueryWrapper<CustomizedOrderCollection> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("collection_number",collectionNumber);
        queryWrapper.ne("status",5);
        queryWrapper.eq("is_deleted",0);
        CustomizedOrderCollection collection = orderCollectionMapper.selectOne(queryWrapper);
        if (collection == null){
            throw new BusinessException(SystemError.CUSTOM_ORDER_4047);
        }
        collection.setStatus(5);
        collection.setRejectMsg(rejectInfo);
        collection.setModifiedId(userId);
        boolean update = updateById(collection);
        if (!update){
            throw new BusinessException(SystemError.SYS_437);
        }
        return Result.success(collection.getId());
    }

    /**
     * 确认收款
     *
     * @param collectionNumber 收款单号
     * @param userId           用户ID
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result confirmCollection(String collectionNumber, Long userId) {
        QueryWrapper<CustomizedOrderCollection> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("collection_number",collectionNumber);
        queryWrapper.ne("status",3);
        queryWrapper.eq("is_deleted",0);
        CustomizedOrderCollection collection = orderCollectionMapper.selectOne(queryWrapper);
        if (collection == null){
            throw new BusinessException(SystemError.CUSTOM_ORDER_4047);
        }
        collection.setStatus(3);
        collection.setModifiedId(userId);
        boolean update = updateById(collection);
        if (!update){
            throw new BusinessException(SystemError.SYS_437);
        }
        return Result.success(collection.getId());
    }

    /**
     * 保险收款-计算保险港币收款金额
     *
     * @param req
     * @return
     */
    @Override
    public Result getHkdAmount(List<GetHkdAmountReq> req) {
        BigDecimal totalHkdAmount = BigDecimal.ZERO;
        for (GetHkdAmountReq item : req){
            BigDecimal hkdAmount = iMainDataCurrencyService.getHkdAmount(item.getCurrencyId(), item.getAmount());
            if (hkdAmount != null){
                totalHkdAmount = totalHkdAmount.add(hkdAmount);
            }
        }
        return Result.success(totalHkdAmount);
    }


    /**
     * 封装参保请求参数
     * @param insurance 保单
     * @return
     */
    public List<AcceptUnderReq> packJoinInsuranceReq(CustomizedOrderInsurance insurance) {
        List<AcceptUnderReq> list = new ArrayList<>();
        AcceptUnderReq acceptReq = new AcceptUnderReq();
        //投保人
        CustomizedOrderTouristInfo applyer = orderTouristInfoMapper.selectById(insurance.getPolicyHolderId());
        if (applyer != null) {
            //投保人資訊
            ApplicantInfo appliGuRelatedPartyDto = new ApplicantInfo();
            appliGuRelatedPartyDto.setAge(applyer.getBirthday().until(LocalDate.now()).getYears() + "");
            appliGuRelatedPartyDto.setBirthDate(DateUtil.fmtLocalDate(applyer.getBirthday(), "yyyy-MM-dd"));
            appliGuRelatedPartyDto.setEmail(applyer.getEmail());
            appliGuRelatedPartyDto.setIdentifyNumber(applyer.getCertificateNumber());
            appliGuRelatedPartyDto.setInsuredName(insurance.getPolicyHolderName());
            appliGuRelatedPartyDto.setInsuredEName(insurance.getPolicyHolderName());
            //证件类型 + 联系地址
            //    String identifyType = PacificUtil.getIdentifyType(applyer.getCertificateTypeId());
            appliGuRelatedPartyDto.setIdentifyType("03");
            appliGuRelatedPartyDto.setSex(applyer.getGender().toString());
            appliGuRelatedPartyDto.setMobilePhone(applyer.getMobile());
            acceptReq.setAppliGuRelatedPartyDto(appliGuRelatedPartyDto);
        }
        //被保人資訊列表
        List<InsuredInfo> guItemAcciListDtoList = new ArrayList<>();
        //旅客参保信息
        QueryWrapper<CustomizedOrderInsurancePriceTourist> touristWrapper = new QueryWrapper<>();
        touristWrapper.eq("insurance_id", insurance.getId());
        touristWrapper.eq("order_id", insurance.getOrderId());
        List<CustomizedOrderInsurancePriceTourist> touristList = orderInsurancePriceTouristMapper.selectList(touristWrapper);
        if (touristList != null && touristList.size() > 0) {
            //被保人資訊列表
            for (CustomizedOrderInsurancePriceTourist tourist : touristList) {
                InsuredInfo guItemAcciListDto = new InsuredInfo();
                guItemAcciListDto.setAge(tourist.getAge().toString());
                guItemAcciListDto.setBirthday(DateUtil.fmtLocalDate(tourist.getBirthday(), "yyyy-MM-dd"));
                guItemAcciListDto.setSex(tourist.getSex().toString());
                guItemAcciListDto.setClientCName(tourist.getEnSurname() + tourist.getEnName());
                guItemAcciListDto.setIdentifyNoA(tourist.getCertificateNumber());
                //证件类型
                //    String identifyTypeA = PacificUtil.getIdentifyType(tourist.getCertificateTypeId());
                guItemAcciListDto.setIdentifyTypeA("03");
                //年龄类型
                //    String remark3 = PacificUtil.getAgeType(tourist.getAge());
                guItemAcciListDto.setRemark3("28");
                guItemAcciListDtoList.add(guItemAcciListDto);
            }
        }
        acceptReq.setGuItemAcciListDtoList(guItemAcciListDtoList);
        //險別咨訊
        acceptReq.setStartDate(DateUtil.fmtLocalDate(insurance.getBeginDate(), "yyyy-MM-dd"));
        acceptReq.setEndDate(DateUtil.fmtLocalDate(insurance.getEndDate(), "yyyy-MM-dd"));
        acceptReq.setStartPlace(insurance.getDeparturePlace());
        acceptReq.setEndPlace(insurance.getDestination());
        list.add(acceptReq);
        return list;
    }

    /**
     * 判断是否设置过该费用
     * @param orderId
     * @param touristId
     * @param mainDataId
     * @param adjustType
     * @return
     */
    private boolean checkFeeAdjust(Long orderId, Long touristId, Long mainDataId,Integer adjustType) {
        QueryWrapper<CustomizedOrderTouristFeeAdjust> feeAdjustWrapper = new QueryWrapper<>();
        feeAdjustWrapper.eq("order_id",orderId);
        feeAdjustWrapper.eq("tourist_id",touristId);
        feeAdjustWrapper.eq("relation_id",mainDataId);
        feeAdjustWrapper.eq("adjust_type",adjustType);
        feeAdjustWrapper.eq("is_deleted",0);
        CustomizedOrderTouristFeeAdjust feeAdjust = orderTouristFeeAdjustMapper.selectOne(feeAdjustWrapper);
        if (feeAdjust == null){
            return true;
        }
        return false;
    }


}
